标签:tree icpc query cst main 输出 des sub dea
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3848 Accepted Submission(s): 1059
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> const int N = 100000 + 11; using namespace std; int t,n,m,tot,li[N],id[N]; struct Query { int ty,num; }quer[N]; int root,cnt; struct Splay_tree { int l,r,cnt,size,f,son[2]; void news(int L,int R) { l = L, r = R, cnt = R - L + 1, size = f = son[0] = son[1] = 0; } void clear() { l = r = cnt = size = f = son[0] = son[1] = 0; } } tree[N<<1]; int get(int x) { return x == tree[tree[x].f].son[1]; } void updata(int x) { tree[x].size = tree[x].cnt; if(tree[x].son[0]) tree[x].size += tree[tree[x].son[0]].size; if(tree[x].son[1]) tree[x].size += tree[tree[x].son[1]].size; } void rotate(int x) { int fa = tree[x].f; int gfa = tree[fa].f; int ze = get(x); tree[fa].son[ze] = tree[x].son[ze^1]; tree[tree[fa].son[ze]].f = fa; tree[x].son[ze^1] = fa, tree[fa].f = x;tree[x].f = gfa; ze = (fa == tree[gfa].son[1]); if(gfa) tree[gfa].son[ze] = x; updata(fa), updata(x); } void splay(int x) { for(int i; i = tree[x].f;rotate(x)) { if(tree[i].f) if(get(x) == get(i)) rotate(i); } root = x; } void insert(int l,int r,int idx) { //cout<<l<<" "<<r<<" "<<endl; if(root == 0){tree[idx].news(l,r),root = idx; return;} int now = root,fa; while(1) { int ze = l > tree[now].l; fa = now; now = tree[fa].son[ze]; if(!now) { tree[idx].news(l,r);tree[idx].f = fa; tree[fa].son[ze] = idx,updata(idx); updata(fa),splay(idx);return; } } } void Init() { scanf("%d%d",&n,&m); char ch[10]; for(int i = 1; i <= m; ++i) { scanf("%s%d",ch,&quer[i].num); if(ch[0] == ‘T‘) quer[i].ty = 1; if(ch[0] == ‘R‘) quer[i].ty = 2; if(ch[0] == ‘Q‘) quer[i].ty = 3; li[i] = quer[i].num; } sort(li + 1,li + 1 + m); tot = 1; for(int i = 2; i <= m; ++i) if(li[i] != li[tot]) li[++tot] = li[i]; li[tot+1] = n + 1; cnt = 1; if(li[1] != 1) insert(1,li[1]-1,1); for(int i = 1; i <= tot; ++i) { insert(li[i],li[i],++cnt); id[i] = cnt; if(li[i] != li[i+1] + 1) insert(li[i] + 1, li[i+1] - 1,++cnt); } } int binary_search(int num) { int l = 1,r = tot; while(l <= r) { int mid = l + ((r-l)>>1); if(li[mid] == num) return id[mid]; if(li[mid] < num) l = mid + 1; else r = mid - 1; } return -1; } int pre(int x) { x = tree[x].son[0]; while(tree[x].son[1]) x = tree[x].son[1]; return x; } void del(int x) { splay(x); if(!tree[x].son[0] && !tree[x].son[1]){root = 0, tree[x].clear(); return;} if(!tree[x].son[0] || !tree[x].son[1]) { int ze = !tree[x].son[1]; int root_y = root; root = tree[x].son[ze^1]; tree[root].f = 0, tree[root_y].clear(); return; } int pres = pre(root); splay(pres); tree[pres].son[1] = tree[x].son[1]; tree[tree[pres].son[1]].f = pres; tree[x].clear(),updata(pres); } void insert_min(int l,int idx) { if(root == 0) {tree[idx].news(l,l),root = idx; return;} int now = root; while(1) { int fa = now; now = tree[fa].son[0]; if(!now) { tree[idx].news(l,l); tree[fa].son[0] = idx; tree[idx].f = fa; updata(idx); updata(fa),splay(idx); return; } } } int query(int ranks) { int now = root; while(1) { int sum = 0; if(tree[now].son[0]) sum += tree[tree[now].son[0]].size; if(sum >= ranks) {now = tree[now].son[0]; continue;} if(sum + tree[now].cnt >= ranks) return tree[now].l + ranks - sum - 1; ranks -= (sum + tree[now].cnt),now = tree[now].son[1]; } } void Solve() { for(int x = 1; x <= m; ++x) { if(quer[x].ty == 1) { int idx = binary_search(quer[x].num); del(idx); insert_min(quer[x].num,idx); } if(quer[x].ty == 3) { int idx = binary_search(quer[x].num); splay(idx); printf("%d\n",tree[tree[idx].son[0]].size + 1); } if(quer[x].ty == 2) printf("%d\n",query(quer[x].num)); } } int main() { scanf("%d",&t); for(int x = 1; x <= t; ++x) { printf("Case %d:\n",x); cnt = 0; root = 0; memset(tree,0,sizeof(tree)); Init(); Solve(); } return 0; }
标签:tree icpc query cst main 输出 des sub dea
原文地址:http://www.cnblogs.com/Ateisti/p/6385682.html