20pts孩子WA傻了呜呜
查看原帖
20pts孩子WA傻了呜呜
229446
ephemere楼主2020/11/12 10:36
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e5+5;
int n,m,a[N];
int tot,tr,root[N],rab[N<<5],lc[N<<5],rc[N<<5];
ll cnt[N<<5];

inline void Update(int p)
{
	cnt[p]=cnt[lc[p]]+cnt[rc[p]];
}

inline int New()
{
	return rab[0]?rab[rab[0]--]:++tot;
}

inline void Throw(int &p)
{
	rab[++rab[0]]=p;lc[p]=rc[p]=cnt[p]=0;
}

void Build(int l,int r,int &p)
{
	p=New();
	if(l==r)
	{
		cnt[p]=(ll)a[l];
		return;	
	}
	
	int mid=(l+r)>>1;
	Build(l,mid,lc[p]);
	Build(mid+1,r,rc[p]);
	
	Update(p);
}
void Split(int l,int r,int x,int y,int &p1,int &p2)
{
	if(l>=x&&r<=y){p2=p1;p1=0;return;}
	
	p2=New();
	int mid=(l+r)>>1;
	if(x<=mid) Split(l,mid,x,y,lc[p1],lc[p2]); 
	if(y>mid) Split(mid+1,r,x,y,rc[p1],rc[p2]);
	
	Update(p2);
	if(!lc[p1]&&!rc[p1]) Throw(p1),p1=0;
	else Update(p1);
}

int Merge(int l,int r,int u,int v)
{
	if(!u||!v) return u|v;
	
	int p=New();
	if(l==r) cnt[p]=cnt[u]+cnt[v];
	else
	{
		int mid=(l+r)>>1;
		lc[p]=Merge(l,mid,lc[u],lc[v]);
		rc[p]=Merge(mid+1,r,rc[u],rc[v]);
		Update(p);
	}
	Throw(u);Throw(v);
	return p;
}

void Change(int l,int r,int x,ll y,int &p)
{
	if(!p) p=New();
	if(l==r)
	{
		cnt[p]+=y;
		return;
	}
	
	int mid=(l+r)>>1;
	if(x<=mid) Change(l,mid,x,y,lc[p]);
	else Change(mid+1,r,x,y,rc[p]);
	
	Update(p);
}

ll Ask(int l,int r,int x,int y,int p)
{
	if(!p) return 0;
	if(l>=x&&r<=y) return cnt[p];
	
	int mid=(l+r)>>1;
	if(y<=mid) return Ask(l,mid,x,y,lc[p]);
	else if(x>mid) return Ask(mid+1,r,x,y,rc[p]);
	else return Ask(l,mid,x,y,lc[p])+Ask(mid+1,r,x,y,rc[p]);
}

int Rank(int l,int r,ll k,int p)
{
	if(l==r) return l;
	
	int mid=(l+r)>>1;
	if(k<=cnt[lc[p]]) return Rank(l,mid,k,lc[p]);
	else return Rank(mid+1,r,k-cnt[lc[p]],rc[p]);
}

int main()
{
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;++i) scanf("%d",&a[i]);
	Build(1,n,root[++tr]);
	int op,p,x,y;ll k;
	for(int i=1;i<=m;++i)
	{
		scanf("%d",&op);
		switch(op)
		{
			case 0:
			{
				scanf("%d %d %d",&p,&x,&y);
				Split(1,n,x,y,root[p],root[++tr]);
				break;
			}
			case 1:
			{
				scanf("%d %d",&x,&y);
				root[x]=Merge(1,n,root[x],root[y]);
				root[y]=0;
				break;
			}
			case 2:
			{
				scanf("%d %lld %d",&p,&k,&x);
				Change(1,n,x,k,root[p]);
				break;
			}
			case 3:
			{
				scanf("%d %d %d",&p,&x,&y);
				if(x>y) printf("0\n");
				else printf("%lld\n",Ask(1,n,x,y,root[p]));
				break;
			}
			case 4:
			{
				scanf("%d %lld",&p,&k);
				if(k>cnt[root[p]]) printf("-1\n");
				else printf("%d\n",Rank(1,n,k,root[p]));
				break;
			}
		}
	}
}
2020/11/12 10:36
加载中...