蒟蒻70分求助
查看原帖
蒟蒻70分求助
104963
Gary88楼主2020/11/14 17:15
#include<cstdio>
#include<map>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<iostream>
using namespace std;
int n,m,cnt,root[4000001],a[1000001];
struct treap
{
	int rnd,w,num,size,ch[2];
}t[8000001];
void pushup(int x)
{
	t[x].size=t[x].num+t[t[x].ch[0]].size+t[t[x].ch[1]].size;
}
void rotate(int &rt,int x)
{
	int y=t[rt].ch[x];
	t[rt].ch[x]=t[y].ch[x^1];
	t[y].ch[x^1]=rt;
	pushup(rt);
	pushup(y);
	rt=y;
}
void insert(int &rt,int k)
{
	if(!rt)
	{
		rt=++cnt;
		t[rt].w=k;
		t[rt].num=t[rt].size=1;
		t[rt].rnd=rand();
		return;
	}
	if(t[rt].w==k)
	{
		t[rt].num++;
		return;
	}
	else if(t[rt].w>k)
	{
		insert(t[rt].ch[0],k);
		if(t[t[rt].ch[0]].rnd>t[rt].rnd)
		{
			rotate(rt,0);
		}
	}
	else
	{
		insert(t[rt].ch[1],k);
		if(t[t[rt].ch[1]].rnd>t[rt].rnd)
		{
			rotate(rt,1);
		}
	}
	pushup(rt);
}
void del(int &rt,int k)
{
	if(t[rt].w>k)
	{
		del(t[rt].ch[0],k);
	}
	else if(t[rt].w<k)
	{
		del(t[rt].ch[1],k);
	}
	else
	{
		if(t[rt].num>1)
		{
			t[rt].num--;
			return;
		}
		else if(t[rt].ch[0]*t[rt].ch[1]==0)
		{
			rt=t[rt].ch[0]+t[rt].ch[1];
		}
		else
		{
			if(t[t[rt].ch[0]].rnd>t[t[rt].ch[1]].rnd)
			{
				rotate(rt,0);
				del(t[rt].ch[1],k);
			}
			else
			{
				rotate(rt,1);
				del(t[rt].ch[0],k);
			}
		}
	}
	pushup(rt);
}
void build(int l,int r,int rt)
{
	for(int i=l;i<=r;i++)
	{
		insert(root[rt],a[i]);
	}
	if(l!=r)
	{
		int mid=(l+r)>>1;
		build(l,mid,rt<<1);
		build(mid+1,r,rt<<1|1);
	}
}
void change(int l,int r,int rt,int x,int k)
{
	del(root[rt],a[x]);
	insert(root[rt],k);
	if(l==r)
	{
		return;
	}
	int mid=(l+r)>>1;
	if(x<=mid)
	{
		change(l,mid,rt<<1,x,k);
	}
	else
	{
		change(mid+1,r,rt<<1|1,x,k);
	}
}
int find(int rt,int k)
{
	if(!rt)
	return 0;
	else if(t[rt].w==k)
	return t[t[rt].ch[0]].size;
	else if(t[rt].w>k)
	return find(t[rt].ch[0],k);
	else
	return t[t[rt].ch[0]].size+t[rt].num+find(t[rt].ch[1],k);
}
int ask(int l,int r,int rt,int L,int R,int k)
{
	if(L<=l&&r<=R)
	{
		return find(root[rt],k);
	}
	int mid=(l+r)>>1;
	int ans=0;
	if(L<=mid)
	{
		ans+=ask(l,mid,rt<<1,L,R,k);
	}
	if(R>mid)
	{
		ans+=ask(mid+1,r,rt<<1|1,L,R,k);
	}
	return ans;
}
int ask1(int L,int R,int k)
{
	int l=0,r=1e8;
	while(l<r)
	{
		int mid=(l+r+1)>>1;
		if(ask(1,n,1,L,R,mid)<k)
		{
			l=mid;
		}
		else
		{
			r=mid-1;
		}
	}
	return r;
}
int ans;
void up(int rt,int k)
{
	if(!rt)
	return;
	if(t[rt].w>=k)
	{
		up(t[rt].ch[0],k);
	}
	else
	{
		ans=max(ans,t[rt].w);
		up(t[rt].ch[1],k);
	}
}
void down(int rt,int k)
{
	if(!rt)
	return;
	if(t[rt].w<=k)
	{
		down(t[rt].ch[1],k);
	}
	else
	{
		ans=min(ans,t[rt].w);
		down(t[rt].ch[0],k);
	}
}
void high(int l,int r,int rt,int L,int R,int k)
{
	if(L<=l&&r<=R)
	{
		up(root[rt],k);
		return;
	}
	int mid=(l+r)>>1;
	if(L<=mid)
	{
		high(l,mid,rt<<1,L,R,k);
	}
	if(R>mid)
	{
		high(mid+1,r,rt<<1|1,L,R,k);
	}
}
void low(int l,int r,int rt,int L,int R,int k)
{
	if(L<=l&&r<=R)
	{
		down(root[rt],k);
		return;
	}
	int mid=(l+r)>>1;
	if(L<=mid)
	{
		low(l,mid,rt<<1,L,R,k);
	}
	if(R>mid)
	{
		low(mid+1,r,rt<<1|1,L,R,k);
	}
}
int main()
{
//	srand((unsigned)time(NULL));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
    	scanf("%d",&a[i]);
    }
    build(1,n,1);
    while(m--)
    {
    	int x,y,z,k;
    	scanf("%d%d%d",&x,&y,&z);
    	switch(x)
    	{
    		case 1:
    			scanf("%d",&k);
    			printf("%d\n",ask(1,n,1,y,z,k)+1);
    			break;
	  		case 2:
    			scanf("%d",&k);
    			printf("%d\n",ask1(y,z,k));
    			break;
    		case 3:
    			change(1,n,1,y,z);
				a[y]=z;
    			break;
    		case 4:
    			scanf("%d",&k);
    			ans=-2147483647;
    			high(1,n,1,y,z,k);
    			printf("%d\n",ans);
    			break;
    		case 5:
    			scanf("%d",&k);
    			ans=2147483647;
    			low(1,n,1,y,z,k);
    			printf("%d\n",ans);
    			break;
    	}
    }
    return 0;
}
2020/11/14 17:15
加载中...