3678: wangxz与OJ
Description
某天,wangxz神犇来到了一个信息学在线评测系统(Online Judge)。由于他是一位哲♂学的神犇,所以他不打算做题。他发现这些题
目呈线性排列,被标记为1~n号,每道题都有一个难度值(可以<=0)。他决定与这些题目玩♂耍。
1、他可以在某个位置插♂入一些难度值特定的题目。
2、他可以吃♂掉(删除)一段题目。
3、他可以查询某个位置的题目的难度值。
维护一个初始有n个元素的序列(标记为1~n号元素),支持以下操作:
0 p a b (0<=p<=当前序列元素个数) (a<=b) 在p位置和p+1位置之间插入整数:a,a+1,a+2,...,b-1,b。若p为0,插在序列最前面;
1 a b (1<=a<=b<=当前序列元素个数) 删除a,a+1,a+2,...,b-1,b位置的元素;
2 p (1<=p<=当前序列元素个数) 查询p位置的元素。
Input
输入第一行包括两个正整数n(1<=n<=20000),m(1<=m<=20000),代表初始序列元素个数和操作个数。
接下来n个整数,为初始序列元素。
接下来m行,每行第一个为整数sym,
若sym=0,接下来有一个非负整数p,两个整数a,b;
若sym=1,接下来有两个正整数a,b;
若sym=2,接下来有一个正整数p;
p、x、y的含义及范围见题目描述。
在任何情况下,保证序列中的元素总数不超过100000。
保证题目涉及的所有数在int内。
Output
对每个sym=2,输出一行,包括一个整数,代表询问位置的元素。
Sample Input
5 3
1 2 3 4 5
0 2 1 4
1 3 8
2 2
1 2 3 4 5
0 2 1 4
1 3 8
2 2
Sample Output
2
HINT
Source
splay题,用到了动态开点
#include<bits/stdc++.h> using namespace std; struct tree{ int len,size,num,ch[2],fa; }t[120005]; int root,tot,n,m; void pushup(int x){ t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+t[x].len; } int chk(int x){ return t[t[x].fa].ch[1]==x; } void rotate(int x){ int y=t[x].fa,z=t[y].fa,k=chk(x),w=t[x].ch[k^1]; t[y].ch[k]=w; t[w].fa=y; t[z].ch[chk(y)]=x; t[x].fa=z; t[x].ch[k^1]=y; t[y].fa=x; pushup(y); pushup(x); } void splay(int x,int goal=0){ while(t[x].fa!=goal){ int y=t[x].fa,z=t[y].fa; if(z!=goal) if(chk(x)==chk(y)) rotate(y); else rotate(x); rotate(x); } if(!goal) root=x; } int kth(int k){ int cur=root; while(1){ if(t[t[cur].ch[0]].size>=k) cur=t[cur].ch[0]; else if(t[t[cur].ch[0]].size+t[cur].len<k) k-=t[t[cur].ch[0]].size+t[cur].len,cur=t[cur].ch[1]; else { k-=t[t[cur].ch[0]].size; if(k!=1){ t[++tot].fa=cur; t[tot].ch[0]=t[cur].ch[0]; t[tot].num=t[cur].num; t[t[cur].ch[0]].fa=tot; t[tot].len=k-1; t[cur].ch[0]=tot; pushup(tot); } if(k!=t[cur].len){ t[++tot].fa=cur; t[tot].ch[0]=t[cur].ch[1]; t[tot].num=t[cur].num+k; t[t[cur].ch[1]].fa=tot; t[tot].len=t[cur].len-k; t[cur].ch[1]=tot; pushup(tot); } t[cur].len=1;t[cur].num+=k-1; return cur; } } } int build(int l,int r){ int mid=(l+r)>>1; if(l!=mid) t[mid].ch[0]=build(l,mid-1),t[t[mid].ch[0]].fa=mid; if(mid!=r) t[mid].ch[1]=build(mid+1,r),t[t[mid].ch[1]].fa=mid; pushup(mid); return mid; } int split(int l,int r){ l=kth(l);r=kth(r+2); splay(l); splay(r,l); return r; } int main(){ scanf("%d%d",&n,&m); t[1].size=t[1].len=1; for(int i=1;i<=n;i++) scanf("%d",&t[i+1].num),t[i+1].size=t[i+1].len=1; t[n+2].size=t[n+2].len=1; tot=n+2; root=build(1,n+2); while(m--){ int opt; scanf("%d",&opt); switch(opt){ case 0:{ int p,a,b; scanf("%d%d%d",&p,&a,&b); int cur=split(p+1,p); t[++tot].fa=cur;t[cur].ch[0]=tot; t[tot].num=a;t[tot].len=t[tot].size=b-a+1; pushup(cur);pushup(root); break; } case 1:{ int a,b; scanf("%d%d",&a,&b); int cur=split(a,b); t[t[cur].ch[0]].fa=t[cur].ch[0]=0; pushup(cur); pushup(root); break; } case 2:{ int p;scanf("%d",&p); int cur=split(p,p); printf("%d\n",t[t[cur].ch[0]].num); break; } } } return 0; }