一、题目
二、解法
这道题 n n n很大,但是询问数很小,我们考虑把所有给定的 x x x作为分割点,然后一个区间直接归为一个点,大小就为这个区间包含的点数,但是离散化时要注意,分割点可能有重复,详细看代码吧。
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <ctime>
#include <map>
using namespace std;
const int MAXN = 1000005;
int read()
{
int x=0,flag=1;char c;
while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*flag;
}
int T,n,q,rt,Index,a[MAXN],op[MAXN],v[MAXN];char s[20];
int ch[MAXN][2],val[MAXN],cnt[MAXN],siz[MAXN],hp[MAXN],l[MAXN];
map<int,int> mp;
struct node
{
int p[2];
node() {p[0]=p[1]=0;}
}emp;
void up(int x)
{
siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+cnt[x];
}
node split(int x,int v)
{
if(!x) return emp;
int d=val[x]<=v;
node y=split(ch[x][d],v);
ch[x][d]=y.p[d^1];
y.p[d^1]=x;
up(x);
return y;
}
node split_(int x,int s)
{
if(!x) return emp;
node y;
if(siz[ch[x][0]]>=s)
{
y=split_(ch[x][0],s);
ch[x][0]=y.p[1];
y.p[1]=x;
}
else
{
y=split_(ch[x][1],s-siz[ch[x][0]]-cnt[x]);
ch[x][1]=y.p[0];
y.p[0]=x;
}
up(x);
return y;
}
int merge(int x,int y)
{
if(!x || !y) return x+y;
if(hp[x]<hp[y])
{
ch[x][1]=merge(ch[x][1],y);
up(x);
return x;
}
ch[y][0]=merge(x,ch[y][0]);
up(y);
return y;
}
void ins(int v,int s,int L)
{
int x=++Index;
cnt[x]=siz[x]=s;val[x]=v;l[x]=L;
ch[x][0]=ch[x][1]=0;hp[x]=rand();
rt=merge(rt,x);
}
int find(int x,int s)
{
if(!x) return 0;
if(siz[ch[x][0]]>=s)
return find(ch[x][0],s);
if(siz[ch[x][0]]+cnt[x]<s)
return find(ch[x][1],s-siz[ch[x][0]]-cnt[x]);
return s-siz[ch[x][0]]+l[x]-1;
}
int main()
{
srand(time(0));
T=read();int Case=0;
while(T--)
{
n=read();q=read();
rt=Index=0;
printf("Case %d:\n",++Case);
for(int i=1;i<=q;i++)
{
scanf("%s",s);
a[i]=v[i]=read();
if(s[0]=='T')
op[i]=0;
if(s[0]=='Q')
op[i]=1;
if(s[0]=='R')
op[i]=2;
}
sort(a+1,a+1+q);
int head=1,tail=1;
for(int i=1;i<=q;i++)
{
if(a[i-1]+1<a[i])
{
ins(++tail,a[i]-a[i-1]-1,a[i-1]+1);
}
if(a[i]!=a[i-1])
{
mp[a[i]]=++tail;
ins(tail,1,a[i]);
}
}
if(a[q]!=n) ins(++tail,n-a[q],a[q]+1);
for(int i=1;i<=q;i++)
{
if(op[i]==0)
{
node x=split(rt,mp[v[i]]-1),y=split_(x.p[1],1);
mp[l[y.p[0]]]=--head;val[y.p[0]]=head;
rt=merge(y.p[0],merge(x.p[0],y.p[1]));
}
if(op[i]==1)
{
node x=split(rt,mp[v[i]]);
printf("%d\n",siz[x.p[0]]);
rt=merge(x.p[0],x.p[1]);
}
if(op[i]==2)
{
printf("%d\n",find(rt,v[i]));
}
}
}
}