题目链接:http://icpc.upc.edu.cn/problem.php?cid=1740&pid=10
题意:n次操作,1 x val y。表示在[ x , y ]范围的时间内,val会显示出来。即在y时间之后该数字val会消失,2 x K 。表示询问在时间x时,显示出来的第k大的数为多少并输出,如果没有这样的数则输出-1.
题解:因为这个n只有1e5,T为100,val有1e6,有一定的诱惑性,让你直接线段树,但会T的,所以我们离线+离散处理一下即可。
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
struct node{
int l,r;
int val;
}tree[N<<2];
struct node1{
int op,pos,val;
int id;
}q[N];
int tot;
int b[N],len;
int ans[N],cnt;
int cmp(const node1 &x,const node1 &y)
{
if(x.pos!=y.pos) return x.pos<y.pos;
else return x.op<y.op;
}
void build(int l,int r,int cur)
{
tree[cur].l=l;
tree[cur].r=r;
tree[cur].val=0;
if(l==r)return;
int mid=(r+l)>>1;
build(l,mid,cur<<1);
build(mid+1,r,cur<<1|1);
}
void pushup(int cur)
{
tree[cur].val=tree[cur<<1].val+tree[cur<<1|1].val;
}
void update(int pos,int cur,int val)
{
if(tree[cur].l==tree[cur].r)
{
tree[cur].val+=val;
return;
}
if(pos<=tree[cur<<1].r)update(pos,cur<<1,val);
else update(pos,cur<<1|1,val);
pushup(cur);
}
int query(int cur,int val)
{
if(tree[cur].l==tree[cur].r)
{
return tree[cur].l;
}
if(tree[cur<<1].val>=val)return query(cur<<1,val);
else return query(cur<<1|1,val-tree[cur<<1].val);
}
int n;
int main()
{
int T;
int nn=1;
scanf("%d",&T);
while(T--)
{
tot=cnt=len=0;
scanf("%d",&n);
int op,l,r,val;
for(int i=1;i<=n;i++)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d%d%d",&l,&val,&r);
tot++;
q[tot].op=1;
q[tot].pos=l,
q[tot].val=val;
tot++;
q[tot].op=2;
q[tot].pos=r+1;
q[tot].val=val;
b[++len]=val;
}
else
{
scanf("%d%d",&l,&val);
tot++;
q[tot].op=3;
q[tot].pos=l;
q[tot].val=val;
q[tot].id=++cnt;
}
}
sort(b+1,b+1+len);
len=unique(b+1,b+1+len)-(b+1);
// cout<<len<<endl;
sort(q+1,q+1+tot,cmp);
build(1,len,1);
int pos;
for(int i=1;i<=tot;i++)
{
if(q[i].op==1)
{
pos=lower_bound(b+1,b+1+len,q[i].val)-b;
update(pos,1,1);
}
else if(q[i].op==2)
{
pos=lower_bound(b+1,b+1+len,q[i].val)-b;
update(pos,1,-1);
}
else
{
// cout<<q[i].id<<endl;
if(tree[1].val<q[i].val) ans[q[i].id]=-1;
else ans[q[i].id]=b[query(1,q[i].val)];
}
}
printf("Case %d:\n",nn++);
for(int i=1;i<=cnt;i++)
printf("%d\n",ans[i]);
}
return 0;
}