我的思路:
用一个桶保存每个数出现的次数,预处理运算时t[i]+=t[i-1]/2;,但是不改变t[i]的值,计算ans。
对于每次改变,删除或更改值时不断向上更新,显然最多更新log次,并且维护ans。
但是交上去以后第3个点WA了,数据很大,调不出来。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define LL long long
const int maxn=3e5+10,maxh=2e5;
int N,lgN,Q,a[maxn],cnt[maxn],ans=0;
int qd(){
int rt=0;char c=getchar();
while(c<'0'||c>'9') c=getchar();
while('0'<=c&&c<='9') rt=(rt<<3)+(rt<<1)+c-48,c=getchar();
return rt;
}
void change1(int t){
for(int i=t;;i++){
cnt[i]++;ans=max(ans,i);
// printf("add to %d:%d\n",i,cnt[i]);
if(cnt[i]&1) break;
}
}
void change2(int t){
int l=0;
for(int i=t;;i++){
cnt[i]--;
if(cnt[i]) l=i;
if(!(cnt[i]&1)) break;
}
if(!cnt[ans]) ans=l;
}
int main(){
N=qd(),Q=qd(),lgN=log2(N)*2+2;
for(int i=1;i<=N;i++) cnt[a[i]=qd()]++;
for(int i=1;i<=maxh+lgN;i++){
cnt[i]+=(cnt[i-1]>>1);
if(cnt[i]) ans=i;
}
// for(int i=1;i<=N;i++) printf("cnt0%d=%d\n",i,cnt[i]);
ans--;
while(Q--){
int x=qd(),y=qd();
change2(a[x]),change1(y);
a[x]=y;
printf("%d\n",ans);
}
return 0;
}
求教应该怎么改。