首页 > 其他分享 >2024初秋集训——提高组 #29

2024初秋集训——提高组 #29

时间:2024-10-02 20:34:09浏览次数:5  
标签:begin end fa int 29 2024 cdot MAXN 初秋

C. 卡片放置

题目描述

有一些卡片,写着两个数字 \(A_i,B_i\)。你要将这些这些卡片排列,其对于你的分数为 \(\max(A_i,B_i)\cdot i\),对于对手的分数为 \(\min(A_i,B_i)\cdot (N-i+1)\)。求令你的分数减对方分数的最大的方案数。

思路

我们来拆式子,这里令 \(A_i\ge B_i\):

\[\begin{array}{l} &A_i\cdot i-B_i\cdot (N-i+1)\\ =&A_i\cdot i-B_i\cdot N+B_i\cdot i-B_i\\ =&(A_i+B_i)\cdot i-(N+1)\cdot B_i \end{array} \]

后一项为定值,不看。很明显只有在 \(A_i+B_i\) 升序排列才最优,只有相同元素之间可以排列。预处理阶乘即可。

空间复杂度 \(O(N)\),时间复杂度 \(O(N\log N)\)。

代码

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 100001, MOD = int(1e9) + 7;

int n, a[MAXN], f[MAXN], ans = 1;

int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  cin >> n;
  f[0] = 1;
  for(int i = 1; i <= n; ++i) {
    cin >> a[i];
    f[i] = 1ll * f[i - 1] * i % MOD;
  }
  for(int i = 1, x; i <= n; ++i) {
    cin >> x;
    a[i] += x;
  }
  sort(a + 1, a + n + 1);
  for(int i = 1, j = 1; i <= n; i = j) {
    for(; j <= n && a[i] == a[j]; ++j) {
    }
    ans = 1ll * ans * f[j - i] % MOD;
  }
  cout << ans;
  return 0;
}

D. 合理架构

题目描述

有一个 \(N\) 个结点,以 \(1\) 为根的树,每个结点都有两个值 \(A_i,B_i\)。你要判断是否符合以下条件:

  • 对于所有 \(u,v\) 使得 \(u\) 是 \(v\) 的祖先,要满足 \(A_u\ge A_v\and B_u\ge B_v\)。
  • 对于所有 \(u\) 不是 \(v\) 的祖先,要满足 \(A_u<A_v\or B_u<B_v\)。

思路

条件 1 显然判断一下父子之间的 \(A,B\) 即可。

对于条件 2,我们求每个点 \(u\) 有多少个点 \(v\) 不满足条件 2。这个就是离线二维数点。

可以发现,只有 \(u\) 的祖先会不满足条件 2。所以只需判断不满足数量是否等于 \(dep_u\) 即可。

空间复杂度 \(O(N)\),时间复杂度 \(O(N\log N)\)。

代码

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 200001, INF = int(1e9) + 1;

struct Tree_Array {
  int n, tr[MAXN];
  void Clear(int m) {
    n = m;
    fill(tr + 1, tr + n + 1, 0);
  }
  void update(int p, int x) {
    for(; p <= n; tr[p] += x, p += (p & -p)) {
    }
  }
  int Getsum(int p) {
    int sum = 0;
    for(; p; sum += tr[p], p -= (p & -p)) {
    }
    return sum;
  }
}tr;

int t, n, a[MAXN], b[MAXN], dep[MAXN], ans[MAXN];
vector<tuple<int, int, int, int>> ve[MAXN];
vector<int> e[MAXN], A, B, vec[MAXN];

bool dfs(int u, int fa) {
  if(fa && (a[u] > a[fa] || b[u] > b[fa])) {
    return 0;
  }
  dep[u] = dep[fa] + 1;
  for(int v : e[u]) {
    if(v != fa && !dfs(v, u)) {
      return 0;
    }
  }
  return 1;
}

void Solve() {
  cin >> n;
  A.clear(), B.clear();
  for(int i = 0; i <= n; ++i) {
    ve[i].clear(), vec[i].clear();
  }
  for(int i = 1; i <= n; ++i) {
    cin >> a[i] >> b[i];
    e[i].clear();
    A.emplace_back(a[i]);
    B.emplace_back(b[i]);
    ans[i] = 0;
  }
  sort(A.begin(), A.end()), A.erase(unique(A.begin(), A.end()), A.end());
  sort(B.begin(), B.end()), B.erase(unique(B.begin(), B.end()), B.end());
  for(int i = 1; i <= n; ++i) {
    a[i] = lower_bound(A.begin(), A.end(), a[i]) - A.begin() + 1;
    b[i] = lower_bound(B.begin(), B.end(), b[i]) - B.begin() + 1;
    ve[a[i] - 1].emplace_back(b[i], n, -1, i);
    ve[n].emplace_back(b[i], n, 1, i);
    vec[a[i]].emplace_back(b[i]);
  }
  for(int i = 1, u, v; i < n; ++i) {
    cin >> u >> v;
    e[u].emplace_back(v);
    e[v].emplace_back(u);
  }
  if(!dfs(1, 0)) {
    cout << "NO\n";
    return;
  }
  tr.Clear(n);
  for(int i = 1; i <= n; ++i) {
    for(int x : vec[i]) {
      tr.update(x, 1);
    }
    for(auto [l, r, x, id] : ve[i]) {
      ans[id] += (tr.Getsum(r) - tr.Getsum(l - 1)) * x;
    }
  }
  for(int i = 1; i <= n; ++i) {
    if(ans[i] != dep[i]) {
      cout << "NO\n";
      return;
    }
  }
  cout << "YES\n";
}

int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  for(cin >> t; t--; Solve()) {
  }
  return 0;
}

标签:begin,end,fa,int,29,2024,cdot,MAXN,初秋
From: https://www.cnblogs.com/yaosicheng124/p/18445062

相关文章

  • CTB2024
    活动官网https://www.chinathinksbig.com/ToDoIMPORTANT10.14提前批报名截止确认要参加的话赶紧把钱交了先注意:付钱(1490好贵)之后才能组队在国庆期间开个会大致考虑一下课题,尽量可以拐一下以下几个点弱势群体环境保护文化保护和传承一些东西数据科技相关......
  • 20241002测试
    move题面:\(T\)组数据,每组数据有\(n\)个数轴上的点\(a_1,a_2,\dots,a_n\)。从原点开始,每次选择一个点未被选择过的点,如果当前在这个点上,那么分数加\(1\),否则向这个点移动\(1\)格。问最高分数。题解:容易发现,要么先往左再往右,要么先往右再往左。先考虑第一种情况,枚举左端......
  • 20241002
    bwtree我们可以设\(dp_{i,0/1}\)表示当前考虑至哪个点,这个节点的子树内选了几个叶子节点#include<bits/stdc++.h>usingnamespacestd;constintN=1e5+5,INF=1e9;intn,a[N],dp[N][2];vector<int>g[N];voiddfs(intu,intf){dp[u][0]=(a[u]=......
  • 2024/10/02 模拟赛总结
    暴力挂惨了,\(0+0+5+0=5\)#A.躲避技能评价:人机高精度由于边权是正数,多走一条边一定更劣,所以能在子树内解决的就尽量不要出来那么对于每一条边,它被遍历的次数是子树内起点与终点数量之差直接枚举每一条边,算答案即可人机高精度//BLuemoon_#include<bits/stdc++.h>using......
  • 2024新生赛-Week1
    F12快捷键f12直接查看字符串xor了解一下XOR运算,AB=C,CA=B使用a数组对输入的字符进行循环运算取出最终的字符串再进行一次xor即可得到flagEzencode进入加密函数后发现是一个base64算法,对表进行了替换,最后有对编码得到的结果进行异或操作.提出最后的密文,进行异或,换表......
  • 2024 ICPC Online 第二场(K)
    #pragmaGCCoptimize("O3,unroll-loops")//#pragmaGCCtarget("avx2,bmi,bmi2,lzcnt,popcnt")//如果在不支持avx2的平台上将avx2换成avx或SSE之一#include<bits/stdc++.h>usingnamespacestd;#definexfirst#defineysecondtypedefpair<int......
  • 【牛客训练记录】2024牛客国庆集训派对day2
    赛后反思只开出来两题,好像水平就这样了TATI题给定一个排列,对于每项可以选择+1或者不加,求逆序对对数最小我们可以思考一下什么情况下可以减少最后答案的逆序对,对于\([4,3]\)或者\([2,1]\)这种情况,将第二个元素+1才能对答案的减少做出贡献,所以只要判断某一位的后面是否有那......
  • zlibrary 最新官方国内可用网址入口及电脑客户端集合(2024持续更新)
    Z-library,被誉为全球范围内最为庞大的数字图书馆之一,其藏书量之丰富令人叹为观止,总计囊括了超过9,826,996册电子书及84,837,646篇学术期刊文章。这座庞大的知识宝库覆盖了从经典文学巨著到前沿理工学科,从人文艺术瑰宝到专业学术论文的广泛领域,几乎能够满足每一位求知者的阅读与学......
  • LoongArch@微处理器体系结构专利技术研究方法@20241002
    微处理器体系结构专利技术研究方法第一辑:X86指令集总述 微处理器体系结构专利技术研究方法第二辑:x86多媒体指令集 微处理器体系结构专利技术研究方法第三辑:X86指令实现专利技术 ......
  • The 2024 Guangdong Provincial Collegiate Programming Contest
    Preface这场据说题挺毒的?但实际打的时候感觉也还好,3h就出了7个题,然后被H卡飞了赛后发现是没有观察到构造的解的性质,把Dinic换成匈牙利就过了,只能说对flow的理解不够B.腊肠披萨神秘string题,被徐神开场一眼秒了,虽然中间我和祁神上去写了三个签到,但徐神还是在1h不......