蔡鸡刚学整体二分输出负无穷求助
查看原帖
蔡鸡刚学整体二分输出负无穷求助
105925
Kari5307_yu楼主2020/5/18 19:02

RT,和一些整体二分AC代码对过了,感觉没啥区别,下面是代码:

#include<bits/stdc++.h>
const int INF=1e9;
using namespace std;
struct node{
	int op,x,y,z;
}q[2000005],lq[2000005],rq[2000005];
int ans[1000005],sum[1000005],a[1000005],pd[1000005],n,m,t,mm;
char c;
inline int lowbit(int x){
	return x&(-x);
}
inline void update(int x,int y){
	while(x<n){
		sum[x]+=y;
		x+=lowbit(x);
	}
}
inline int query(int x){
	int ans=0;
	while(x){
		ans+=sum[x];
		x-=lowbit(x);
	}
	return ans;
}
void divide(int l,int r,int s,int t){
	if(s>t)return;
	if(l==r){
		for(int i=s;i<=t;i++)
			if(q[i].op>0)ans[q[i].op]=l;
		return;
	}
	int mid=l+r>>1;
	int ls=0,rs=0; 
	for(int i=s;i<=t;i++){
		if(q[i].op==0){
			if(q[i].y<=mid){
				update(q[i].x,q[i].z);
				lq[++ls]=q[i];
			}
			else rq[++rs]=q[i];
		}
		else{
			int cnt=query(q[i].y)-query(q[i].x-1);
			if(cnt>=q[i].z)lq[++ls]=q[i];
			else {
				q[i].z-=cnt;
				rq[++rs]=q[i];
			}
		}
	}
	for(int i=s;i<=t;i++)
		if(q[i].op==0&&q[i].y<=mid)
			update(q[i].x,-q[i].z);
	for(int i=1;i<=ls;i++)
		q[s+i-1]=lq[i];
	for(int i=1;i<=rs;i++)
		q[s+ls+i-1]=rq[i];
	divide(l,mid,s,s+ls-1);
	divide(mid+1,r,s+ls,t);
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",&q[++t].y),q[t].op=0,q[t].x=i,q[t].z=1,a[i]=q[t].y;
	scanf("\n");
	for(int i=1;i<=m;i++){
		scanf("%c ",&c);
		if(c=='Q')scanf("%d%d%d\n",&q[++t].x,&q[t].y,&q[t].z),q[t].op=i,pd[i]=1;
		if(c=='C'){
			int x,y;
			scanf("%d%d\n",&x,&y);
			q[++t].op=0;
			q[t].x=x;
			q[t].y=a[x];
			q[t].z=-1;
			q[++t].op=0;
			q[t].x=x;
			q[t].y=y;
			q[t].z=1;
			a[x]=y;
		}
	}
	for(int i=1;i<=t;i++)
		printf("%d %d %d %d\n",q[i].op,q[i].x,q[i].y,q[i].z);
	divide(-INF,INF,1,t);
	for(int i=1;i<=m;i++)
		if(pd[i])printf("%d\n",ans[i]);
	return 0;
}
2020/5/18 19:02
加载中...