Dynamic Rankings

实际上就是将单个询问的二分修改为同时处理多个询问
考虑二分答案
对于每一个mid,考虑询问是归为[l,mid]或[mid+1,r]
统计修改的贡献,同样将修改归为[l,mid]或[mid+1,r]

#include <bits/stdc++.h>
#define INF 1e9
using namespace std;
const int MAXN=3e5+5;
int n,m;
int x;
int a[MAXN];
int ans[MAXN];
struct Query{
	int op;
	int l,r,key;
	int pos,val;
}query[MAXN],lq[MAXN],rq[MAXN];
int Bit[MAXN];
int lowbit(int x)
{
	return x&(-x);
}
void update(int x,int k)
{
	for(int i=x;i<=n;i+=lowbit(i))
	{
		Bit[i]+=k;
	 } 
	 return;
}
int Sum(int k)
{
	int res=0;
	for(int i=k;i>=1;i-=lowbit(i))
	{
		res+=Bit[i];
	}
	return res;
}
char s[105];
int l,r,k;
void solve(int lv,int rv,int st,int ed)//递归处理[l,r]可能的答案对[st,ed]的答案 
{
	if(st>ed)
	{
		return;
	}
	//printf("%d %dfuck\n",st,ed);
	if(lv==rv)
	{
		
		for(int i=st;i<=ed;i++)
		{
			if(query[i].op>=1)
			{
				ans[query[i].op]=lv;
			}
		}//边界 
		return;
	}
	int mid=(lv+rv)>>1;
	int lt=0;
	int rt=0;
	for(int i=st;i<=ed;i++)
	{
		if(query[i].op<=0)
		{
			if(query[i].val<=mid)
			{
				int xfg=query[i].op;
				if(!xfg)
				{
					xfg++;
				}
				update(query[i].pos,xfg);
				lq[++lt]=query[i];
				//考虑小于mid的对询问的贡献	
			}
			else
			{
				rq[++rt]=query[i];
			}
		}
		else
		{
			int cg=(Sum(query[i].r)-Sum(query[i].l-1));
			int rest=query[i].key-cg;
			//如果rest>0,那么说明<mid的无法完全消耗排名 
			if(rest<=0)
			{
				lq[++lt]=query[i];	
			}
			else
			{
				query[i].key=rest;
				rq[++rt]=query[i];
			}	
		}
	}
	
	for(int i=1;i<=lt;i++)
	{
		if(lq[i].op<=0)
		{
			int xfg=lq[i].op;
			if(!xfg)
			{
				xfg++;
			}
	//		printf("%d\n",lq[i].pos);
			update(lq[i].pos,-xfg);//清空标记 
		}
	
	}
	int cnt_q=st-1;
	for(int i=1;i<=lt;i++)
	{
		query[++cnt_q]=lq[i];
	}
	for(int i=1;i<=rt;i++)
	{
		query[++cnt_q]=rq[i];
	}
	solve(lv,mid,st,st+lt-1);
	solve(mid+1,rv,st+lt,ed);//递归 
}
int main() {
	
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		ans[i]=-1;
	}
	int cnt_query=0;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&x);
		a[i]=x;
		query[++cnt_query].op=0;
		query[cnt_query].val=x;
		query[cnt_query].pos=i;
	 } //初始的值 
	 for(int i=1;i<=m;i++)
	 {
	 	scanf("%s",s);
	 	if(s[0]=='Q')
	 	{
	 		scanf("%d %d %d",&l,&r,&k);
			 query[++cnt_query].op=i;
			 query[cnt_query].l=l;
			 query[cnt_query].r=r;
			 query[cnt_query].key=k;
		 }
		 else
		 {
		 	scanf("%d %d",&k,&x);
		 	query[++cnt_query].op=-1;
		 	query[cnt_query].pos=k;
		 	query[cnt_query].val=a[k];
		 	a[k]=x;
		 	query[++cnt_query].op=0;
		 	query[cnt_query].pos=k;
		 	query[cnt_query].val=a[k];
		 }//裁成两个修改 
	}
	solve(0,INF,1,cnt_query);
	for(int i=1;i<=m;i++)
	{
	//	printf("%d\n",ans[i]);
		if(ans[i]!=-1)
		{
			printf("%d\n",ans[i]);
		}
	}
}
posted @ 2022-02-16 22:00  kid_magic  阅读(41)  评论(1编辑  收藏  举报