1 条题解
-
0
赛时不会某个结论,被
https://www.luogu.com.cn/user/565742下文认为 同阶。
令奶牛 的得票数为 ,记 。显然两头奶牛 能当选的充要条件为 。
考虑一种 做法:对于每种 的值 ,找出最小和最大的 满足 ,枚举其中一个出现次数 ,找出 对应的最小的 ,使用双指针找出 中的 ,将所有情况取最大值即为答案。需要用到的值都可以用
set维护。赛时卡在这一步了,但事实上上面的做法离正解就差一个十分关键的结论:若一个正整数序列 满足 ,那么 中元素的种类数的量级是 的。证明考虑如何卡满到这个上界,只需要构造 即可。由于 ,所以 的值只有本质不同的 种。
于是对于上面的暴力做法,如果只考虑至少对应着一个 的 ,时间复杂度就是 的。
放代码:
#include<bits/stdc++.h> using namespace std; int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n,q; cin>>n>>q; vector<int> a(n),c(n); for(auto &i:a)cin>>i,c[--i]++; vector<set<int> > s(n+1); set<int> v; // s 是每个 c 对应着那些 x // v 是至少对应着一个 x 的 c 的集合 for(int i:a)s[c[i]].emplace(i),v.emplace(c[i]); while(q--){ int p,x,r=0; cin>>p>>x,p--,x--; s[c[a[p]]].erase(a[p]); s[c[x]].erase(x); if(s[c[a[p]]].empty())v.erase(c[a[p]]); if(s[c[x]].empty())v.erase(c[x]); s[--c[a[p]]].emplace(a[p]); s[++c[x]].emplace(x); v.emplace(c[a[p]]),v.emplace(c[x]),a[p]=x; vector<int> e(v.begin(),v.end()); for(int i=0,p=e.size()-1,mx=0;i<e.size();i++) if(e[i]){ while(p>=0&&e[p]&&e[p]+e[i]>=e.back()) mx=max(mx,*prev(s[e[p]].end())),p--; r=max(r,mx-*s[e[i]].begin()); } // 双指针求解过程 cout<<r<<'\n'; } return 0; }
- 1
信息
- ID
- 1566
- 时间
- 3000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- 递交数
- 37
- 已通过
- 6
- 上传者