CF1862G(multiset集合)
题意:
一个数组n可以进行如下操作:
先对数组排序,对 ,然后去重;重复该操作直至元素变为1,对数组k次询问,每次询问x,k,将 ,计算进行若干次操作后数组最后一个数
思路:
考虑对一个确定的数组操作,每次操作会使 的差值减1,当两者相等时消除一个,每次操作 ,且最后一个树必定包含 ,所以最后的数为 ,b为相邻的差值,所以考虑维护每次两个数的最大值,用multiset维护,每次删除差值用extract(如果有多个相同的值只会删一个),删除a元素要删除该节点
cpp
void solve(){
int n;
cin>>n;
vector<int> a(n);
for(int i=0;i<n;i++)cin>>a[i];
multiset<int> s,d{0};
auto add=[&](int x){
auto it=s.insert(x);
auto r=next(it);
if(it!=s.begin())d.insert(x-*prev(it));
if(r!=s.end())d.insert(*r-x);
if(it!=s.begin()&&r!=s.end()){
d.extract(*r-*prev(it));
}
};
auto del=[&](int x){
auto it=s.find(x);
auto r=next(it);
if(it!=s.begin())d.extract(x-*prev(it));
if(r!=s.end())d.extract(*r-x);
if(it!=s.begin()&&r!=s.end()){
d.insert(*r-*prev(it));
}
s.erase(it);
};
for(int i=0;i<n;i++)add(a[i]);
int q;
cin>>q;
while(q--){
int x,y;
cin>>x>>y;
x--;
del(a[x]);
a[x]=y;
add(a[x]);
cout<<*s.rbegin()+*d.rbegin()<<" ";
}
cout<<"\n";
}