悬关求调,分块30pts
查看原帖
悬关求调,分块30pts
690160
ask_silently楼主2023/8/17 15:49

样例过了,思路应该没问题,应该是细节问题,但死活找不出来 恼

#include <bits/stdc++.h>
using namespace std;

const int N=5e5+10;

int n,m,bsz,bcnt;
long long a[N],bel[N],bl[N],br[N],sum[N],mei[N],pd[N];

inline int read(){
	int t=0,f=1;
	register char c=getchar();
	while (c<48||c>57) f=(c=='-')?(-1):(f),c=getchar();
	while (c>=48&&c<=57)t=(t<<1)+(t<<3)+(c^48),c=getchar();
	return f*t;
}

inline long long readl(){
	long long t=0,f=1;
	register char c=getchar();
	while (c<48||c>57) f=(c=='-')?(-1):(f),c=getchar();
	while (c>=48&&c<=57)t=(t<<1)+(t<<3)+(c^48),c=getchar();
	return f*t;
}

void init(){
	bsz=sqrt(5e5+5),bcnt=ceil((double)(5e5+5)/bsz);
	for(int i=1;i<=bcnt;i++){
		bl[i]=(i-1)*bsz+1,br[i]=min((int)(5e5+5),i*bsz);
		for(int j=bl[i];j<=br[i];j++) bel[j]=i,sum[i]+=a[j],mei[i]++;
	}
}

int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++) a[i]=readl(),pd[i]=1;
	init();
	while(m--){
		char c;
		cin>>c;
		if(c=='C'){
			int x=read(),y=read();
			if(!pd[x]) continue;
			sum[bel[x]]-=a[x];
			a[x]-=y;
			sum[bel[x]]+=a[x];
		}else if(c=='I'){
			int x=read(),y=read();
			if(pd[x]){
				sum[bel[x]]-=a[x];
				a[x]=y;
				sum[bel[x]]+=a[x];
			}else{
				sum[bel[x]]+=y;
				mei[bel[x]]++;
				a[x]=y;
				pd[x]=1;
			}
		}else if(c=='Q'){
			long long x=0;
			for(int i=1;i<=bcnt;i++) x+=sum[i];
			cout<<x<<'\n';
		}else{
			int x=read();
			int idx=0,biao;
			for(int i=1;i<=bcnt;i++){
				idx+=mei[i];
				if(idx>=x){idx-=mei[i];biao=i;break;}
			}
			for(int i=bl[biao];i<=br[biao];i++){
				if(a[i]) idx++;
				if(idx==x){
					mei[biao]--;
					sum[biao]-=a[i];
					a[i]=0;
					pd[i]=0;
					break;
				}
			}
		}
	}
	return 0;
}

2023/8/17 15:49
加载中...