1 条题解
-
0
自动搬运
来自洛谷,原作者为

极寒神冰
**搬运于
2025-08-24 22:25:49,当前版本为作者最后更新于2022-01-01 22:50:50,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
先考虑每次直接判断每个 是否可行。
已经有 ,剩下的 个人进行操作,可以假设这 个人联合对抗你,然后就有一个显然的策略:
不管 是否等于 ,总是会优先选择一个等于 的数将其覆盖,然后尽量让某个 的数出现尽可能多。
因此需要考虑 至少有几个:
设原先有 个 , 中有 个不等于 的数,则一个显然的下界是 。
特别的,当 时需要对 取 。记 至少有 。
然后要考虑其他数最多能出现多少次:
对于每个数 ,统计出 在 中的出现次数 ,以及在 中的出现次数 。显然 最后最多出现 。
显然如果 ,则你是必胜的。但如果 ,是否有可能必胜呢?
事实上,当且仅当 此时有 你才是必胜的,否则只要其他人联合起来就一定可以让 出现 次, 出现 次。
这样直接做的时间复杂度是 。
考虑优化,发现对于不同的 ,大部分的量都是相同,除了两部分:
-
首先就是 会发生 的变化,而 不变, 仍然可以快速得到。
-
原先 出现次数会 , 的出现次数会 。
若 ,则 会比原先 ,需要单独判断。
对于 出现次数 ,可以预处理出是否有其他的 与 有相同或更大的值。
同样也可以快速得到。
时间复杂度 。
#include<bits/stdc++.h> #define R(i,a,b) for(int i=(a),i##E=(b);i<=i##E;i++) #define L(i,a,b) for(int i=(b),i##E=(a);i>=i##E;i--) using namespace std; int n,p,c,h; int b[1111111],cnt[1111111]; int l[1111111]; vector<int>ans; int mx,mmx,cy; inline int check(int x) { if(n==1&&l[p]==h) return 1; --cnt[b[x]]; ++cnt[l[1]]; int del=cnt[h]-cy; bool ok=1; if(del<=0) ok=0; if(cnt[mx]>=del) ok=0; if(cnt[mmx]>=del) ok=0; if(l[1]!=h&&cnt[l[1]]>=del) ok=0; ++cnt[b[x]]; --cnt[l[1]]; return ok; } signed main() { ios::sync_with_stdio(false); cin.tie(NULL); cin>>n>>p>>c>>h; R(i,1,n) cin>>b[i],++cnt[b[i]]; R(i,1,p) cin>>l[i]; R(i,2,p) if(l[i]!=h) ++cy,++cnt[l[i]]; //cout<<cy<<endl; R(i,1,c) if(i!=h) { if(cnt[i]>cnt[mx]) mmx=mx,mx=i; else if(cnt[i]>cnt[mmx]) mmx=i; } R(i,1,n) if(check(i)) ans.emplace_back(i); cout<<ans.size()<<endl; for(int x:ans) cout<<x<<' '; cout<<endl; } -
- 1
信息
- ID
- 6166
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者