Codeforces - Nastya and King-Shamans

題目鏈接:Codeforces - Nastya and King-Shamans


顯然,每次 * 2倍增最多進行log次,所以我們在線段樹上二分,找到第一個 2 * a[i] 的位置即可。

然後線段樹維護前綴和的max


AC代碼:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int n,q,a[N],mx[N<<2],lazy[N<<2];
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read(){
    int x=0,f=1; char ch=gc();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
    return x*f;
}
#define mid (l+r>>1)
inline void push_down(int p){
	mx[p<<1]+=lazy[p],mx[p<<1|1]+=lazy[p];
	lazy[p<<1]+=lazy[p],lazy[p<<1|1]+=lazy[p];
	lazy[p]=0; 
}
void change(int p,int l,int r,int ql,int qr,int v){
	if(l==ql&&r==qr){mx[p]+=v,lazy[p]+=v; return ;}
	push_down(p);
	if(qr<=mid)	change(p<<1,l,mid,ql,qr,v);
	else if(ql>mid)	change(p<<1|1,mid+1,r,ql,qr,v);
	else change(p<<1,l,mid,ql,mid,v),change(p<<1|1,mid+1,r,mid+1,qr,v);
	mx[p]=max(mx[p<<1],mx[p<<1|1]);
}
int ask(int p,int l,int r,int x){
	if(l==r)	return mx[p];
	push_down(p);
	if(x<=mid)	return ask(p<<1,l,mid,x);
	else	return ask(p<<1|1,mid+1,r,x);
}
int rk(int p,int l,int r,int v){
	if(l==r)	return l;
	push_down(p);
	if(mx[p<<1]>=v)	return rk(p<<1,l,mid,v);
	else	return rk(p<<1|1,mid+1,r,v);
}
signed main(){
	n=read(),q=read();
	for(int i=1;i<=n;i++)	a[i]=read(),change(1,1,n,i,n,a[i]);
	for(int i=1,x,y,pos,ok;i<=q;i++){
		x=read(),y=read(); change(1,1,n,x,n,y-a[x]); a[x]=y; pos=1; ok=-1;
		if(a[1]==0)	ok=1;
		while(pos<n&&ok==-1){
			int tmp=ask(1,1,n,pos);
			int v=rk(1,1,n,2*tmp);
			if(a[v]==ask(1,1,n,v-1))	ok=v;
			pos=v;
		}
		printf("%lld\n",ok);
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章