【treap】6145 - Version Controlled IDE 2012合艾赛区E题
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4156
比赛当时,我们队就一直坑在这个题上了,没有人看到最后一小段,一直用可以离线的splay企图AC,结果当然很惨烈=。=,耗费了半场比赛在这么一个不存再的题目上面。。。
题目本质是一个普通的平衡树,但是限定了只能在线,所以写一个普通的函数式treap即可通过,参考了范浩强神牛的讲义,突然发现这个东西可以特别好写比普通的还短,具体看代码吧。。思路啥的仔细看代码不难懂。
View Code
1 //By Lin 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 using namespace std; 6 7 struct Node{ 8 int key,weight,size; 9 Node *l,*r; 10 Node(int _key , int _weight, Node *_l, Node* _r): 11 key(_key),weight(_weight),l(_l),r(_r){ 12 size = 1; 13 if ( l ) size += l->size; 14 if ( r ) size += r->size; 15 } 16 Node *newnode(int key){ 17 return new Node(key,rand(),NULL,NULL); 18 } 19 inline int lsize(){ return l?l->size:0; } 20 inline int rsize(){ return r?r->size:0; } 21 }*root[50005]; 22 Node* Meger(Node *a , Node *b ){ 23 if ( !a || !b ) return a?a:b; 24 return a->weight>b->weight? 25 new Node(a->key,a->weight,a->l,Meger(a->r,b)): 26 new Node(b->key,b->weight,Meger(a,b->l),b->r); 27 } 28 Node* Split_L(Node *a ,int size ){ 29 if ( !a || size == 0 ) return NULL; 30 return a->lsize() < size? 31 new Node(a->key,a->weight,a->l,Split_L(a->r,size-1-a->lsize())): 32 Split_L(a->l,size); 33 } 34 Node* Split_R(Node *a ,int size ){ 35 if ( !a || size == 0 ) return NULL; 36 return a->rsize() < size? 37 new Node(a->key,a->weight,Split_R(a->l,size-1-a->rsize()),a->r): 38 Split_R(a->r,size); 39 } 40 int Ask( Node *a ,int k ){ 41 if ( a->lsize() >= k ) return Ask(a->l,k); 42 k -= a->lsize()+1; 43 if ( k == 0 ) return a->key; 44 return Ask(a->r,k); 45 } 46 int len = 0; 47 48 int main(){ 49 int d = 0 , cas; 50 scanf("%d", &cas ); 51 root[0] = NULL; 52 int cnt = 1,kind,v,p,c; 53 char s[1005]; 54 while ( cas -- ) { 55 scanf("%d", &kind ); 56 if ( kind == 1 ) { 57 scanf("%d%s", &p , s ); 58 p-=d; 59 Node *l = Split_L(root[cnt-1],p), 60 *r = Split_R(root[cnt-1],len-p); 61 for (int i = 0; s[i]; i++ ){ 62 l = Meger(l,new Node(s[i],rand(),NULL,NULL)); 63 len++; 64 } 65 root[cnt++] = Meger(l,r); 66 } 67 else if ( kind == 2){ 68 scanf("%d%d", &p , &c ); 69 p-=d,c-=d; 70 Node *l = Split_L(root[cnt-1],p-1), 71 *r = Split_R(root[cnt-1],len-p-c+1); 72 len -= c; 73 root[cnt++] = Meger(l,r); 74 } 75 else{ 76 scanf("%d%d%d", &v, &p , &c ); 77 v-=d,p-=d,c-=d; 78 char ch; 79 for (int i = p; i<p+c; i++) { 80 printf("%c", ch = Ask(root[v],i) ); 81 if ( ch == 'c' ) d++; 82 } 83 puts(""); 84 } 85 } 86 return 0; 87 }