[宠物收养所] ( Splay树 )
From http://www.lydsy.com/JudgeOnline/problem.php?id=1208
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/************************************************************** Problem: 1208 User: leezy Language: C++ Result: Accepted Time:192 ms Memory:2840 kb ****************************************************************/ #include <iostream> #include <stdio.h> #include <string.h> #include <cmath> using namespace std; #define N 80005 #define M 1000000 #define INF 0x7fffffff struct { int v,l,r,p,f; } t[N]; int cnt, rt; int alloc(int v, int f){ t[++cnt].v = v; t[cnt].f = f; t[cnt].l = t[cnt].r = t[cnt].p = 0; return cnt; } void rot_r(int x) { int y = t[x].l; t[x].l = t[y].r; t[t[y].r].p = x; t[y].p = t[x].p; if ( !t[x].p ) rt = y; else if ( t[t[x].p].l == x ) t[t[x].p].l = y; else t[t[x].p].r = y; t[y].r = x; t[x].p = y; } void rot_l(int x) { int y = t[x].r; t[x].r = t[y].l; t[t[y].l].p = x; t[y].p = t[x].p; if ( !t[x].p ) rt = y; else if ( t[t[x].p].l == x ) t[t[x].p].l = y; else t[t[x].p].r = y; t[y].l = x; t[x].p = y; } void maintains(int x) { while ( t[x].p ){ int p1 = t[x].p; if ( t[p1].l == x ){ if ( !t[p1].p ) rot_r(p1); else { int p2 = t[p1].p; if ( t[p2].l == p1 ){ rot_r(p2); rot_r(p1); } else { rot_r(p1); rot_l(p2); } } } else { if ( !t[p1].p ) rot_l(p1); else { int p2 = t[p1].p; if ( t[p2].r == p1 ){ rot_l(p2); rot_l(p1); } else { rot_l(p1); rot_r(p2); } } } } } void ins(int v, int f){ int k = alloc(v, f); int x = rt, y = 0; while ( x ){ y = x; if ( t[x].v < v ) x = t[x].r; else x = t[x].l; } t[k].p = y; if ( !y ) rt = k; else if ( t[y].v < v ) t[y].r = k; else t[y].l = k; maintains(k); } int child_1(int x){ if ( t[x].l ){ for (x=t[x].l; t[x].r; ) x = t[x].r; return x; } while ( t[x].p && t[t[x].p].l == x ) x = t[x].p; return t[x].p; } int child_2(int x){ if ( t[x].r ){ for (x=t[x].r; t[x].l; ) x = t[x].l; return x; } while ( t[x].p && t[t[x].p].r == x ) x = t[x].p; return t[x].p; } void del(int z){ int y = 0; if ( !t[z].l || !t[z].r ) y = z; else y = child_2(z); int x = t[y].l; if ( !x ) x = t[y].r; if ( x ) t[x].p = t[y].p; if ( !t[y].p ) rt = x; else if ( t[t[y].p].l == y ) t[t[y].p].l = x; else t[t[y].p].r = x; if ( y != z ){ t[z].v = t[y].v; t[z].f = t[y].f; } } int abs_t(int x, int y){ if ( x < y ) return (y-x); return (x - y); } int main() { //const char path[] = "D:\\Project\\AlgorithmExam\\test.txt"; //freopen(path, "r+", stdin); int n; while ( scanf("%d",&n) != EOF ){ cnt = rt = 0; int a,b,sum = 0; for (int i = 0; i < n; ++i ){ scanf("%d%d", &a,&b); ins(b, a); int ma = child_1(rt); int mb = child_2(rt); if ( !ma && !mb ) continue; if ( !ma ){ if ( t[mb].f ^ t[rt].f ){ sum = (abs_t(t[mb].v,t[rt].v) + sum)%M; del(mb);del(rt); } } else if ( !mb ){ if ( t[ma].f ^ t[rt].f ){ sum = (abs_t(t[ma].v,t[rt].v) + sum)%M; del(ma);del(rt); } } else{ int d1 = INF, d2 = INF; if ( t[ma].f ^ t[rt].f ) d1 = abs_t(t[ma].v,t[rt].v); if ( t[mb].f ^ t[rt].f ) d2 = abs_t(t[mb].v,t[rt].v); if ( d1 == INF && d2 == INF ) continue; sum = (sum + min(d1,d2))%M; if ( d1 < d2 ) del(ma),del(rt); else if ( d1 == d2 ){ if ( t[ma].v < t[mb].v ) del(ma),del(rt); else del(mb),del(rt); }else del(mb),del(rt); } } printf("%d\n", sum); } return 0; }
用跳表做了一次, NND, 用time(0)做随机数种子,会一直RE。。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /************************************************************** 2 Problem: 1588 3 User: leezy 4 Language: C++ 5 Result: Accepted 6 Time:156 ms 7 Memory:2260 kb 8 ****************************************************************/ 9 10 #include <stdio.h> 11 #include <string.h> 12 #include <time.h> 13 #include <stdlib.h> 14 #define N 40015 15 #define M 1000000 16 #define INF 0x6fffffff 17 #define MAX_LEVEL 32 18 #define NIL (0) 19 #define min(a,b) ((a)<(b))?(a):(b) 20 typedef struct tagSkipListNode{ 21 int key; 22 tagSkipListNode* next, *prev, *up, *down; 23 } Node; 24 Node Nil; 25 Node* List[MAX_LEVEL], *Upd[MAX_LEVEL]; 26 int top; 27 void Init(int x) 28 { 29 top = -1; 30 Nil.key = INF; 31 srand(x); 32 } 33 Node* NewNode(int key){ 34 Node* p = (Node*)malloc(sizeof(Node)); 35 p->key = key; 36 p->prev = p->next = &Nil; 37 p->up = p->down = &Nil; 38 return p; 39 } 40 int Find_LessEqual(int key){ 41 if ( top < 0 ) return 0; 42 int k = top; 43 Node* p = List[k]; 44 while ( k >= 0 ){ 45 for (Node* q = p->next; q->key <= key; p = q, q = p->next ); 46 Upd[k--] = p; 47 p = p->down; 48 } 49 return (Upd[0]->key == key)?(1):(0); 50 } 51 int Ins(int key){ 52 if ( Find_LessEqual(key) ) return 0; 53 int k = 0; 54 for (float r = 0; r < 0.5 && k < MAX_LEVEL; r = ((float)rand())/RAND_MAX) { ++k; } 55 for (; top + 1 < k; ){ 56 Node* p = NewNode(-INF); 57 if ( -1 == top ) List[++top] = p; 58 else { 59 List[top]->up = p; p->down = List[top]; 60 List[++top] = p; 61 } 62 Upd[top] = p; 63 } 64 Node* top2 = 0; 65 for (int i = 0; i < k; ++i ){ 66 Node* p = NewNode(key); 67 Node* q = Upd[i]->next; 68 p->next = q; q->prev = p; 69 Upd[i]->next = p; p->prev = Upd[i]; 70 if ( !top2 ) top2 = p; 71 else { 72 p->down = top2; top2->up = p; 73 top2 = p; 74 } 75 } 76 77 Node* x = Upd[0], *y = x->next, *z = y->next; 78 if ( x->key == -INF && z->key == INF ) return y->key; 79 if ( x->key == -INF && z->key != INF ) return abs(y->key-z->key); 80 if ( x->key != -INF && z->key == INF ) return abs(x->key-y->key); 81 return min(abs(x->key-y->key), abs(y->key-z->key)); 82 } 83 int main() 84 { 85 int n, sum = 0; 86 while ( scanf("%d", &n) != EOF ){ 87 //char op[5]; 88 Init(n+sum); 89 sum = 0; 90 for ( int i = 0; i < n; ++i ){ 91 int d = 0; 92 if ( scanf("%d", &d) == EOF ) d = 0; 93 sum += Ins(d); 94 //Dump(); 95 } 96 printf("%d\n", sum); 97 } 98 return 0; 99 }