BZOJ2141 排队
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2141
Description
排排坐,吃果果,生果甜嗦嗦,大家笑呵呵。你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和。红星幼儿园的小朋友们排起了长长地队伍,准备吃果果。不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观。设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为:满足ihj的(i,j)数量。幼儿园阿姨每次会选出两个小朋友,交换他们的位置,请你帮忙计算出每次交换后,序列的杂乱程度。为方便幼儿园阿姨统计,在未进行任何交换操作时,你也应该输出该序列的杂乱程度。
Input
第一行为一个正整数n,表示小朋友的数量;第二行包含n个由空格分隔的正整数h1,h2,…,hn,依次表示初始队列中小朋友的身高;第三行为一个正整数m,表示交换操作的次数;以下m行每行包含两个正整数ai和bi¬,表示交换位置ai与位置bi的小朋友。
Output
输出文件共m行,第i行一个正整数表示交换操作i结束后,序列的杂乱程度。
ZKW线段树套Treap,膜着CZL神犇的代码愣是找出了一堆bug
依然是十分二逼的写法(ZKW线段树连用指针都难)
注意query函数中的 if (l > r) return 0; 一句
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #define rep(i,l,r) for(int i=l; i<=r; i++) 6 #define clr(x,y) memset(x,y,sizeof(x)) 7 #define travel(x) for(Edge *p=last[x]; p; p=p->pre) 8 using namespace std; 9 const int INF = 0x3f3f3f3f; 10 const int maxn = 20010; 11 inline int read(){ 12 int ans = 0, f = 1; 13 char c = getchar(); 14 for(; !isdigit(c); c = getchar()) 15 if (c == '-') f = -1; 16 for(; isdigit(c); c = getchar()) 17 ans = ans * 10 + c - '0'; 18 return ans * f; 19 } 20 int n,m,l,r,M,ans,h[maxn]; 21 struct Node{ 22 Node *ch[2]; 23 int v,s,w,r; 24 inline void maintain(){ 25 s = ch[0]->s + ch[1]->s + w; 26 } 27 }; 28 Node TREAP[525000],*pt = TREAP,*null = pt++; 29 inline Node *newnode(int x){ 30 pt->v = x; pt->s = pt->w = 1; pt->r = rand(); 31 pt->ch[0] = pt->ch[1] = null; 32 return pt++; 33 } 34 inline void rotate(Node *&o,int d){ 35 Node *k = o->ch[d^1]; o->ch[d^1] = k->ch[d]; k->ch[d] = o; 36 o->maintain(); k->maintain(); o = k; 37 } 38 struct Treap{ 39 Node *root; 40 Treap(){ 41 root = null; 42 } 43 void ins(int x,Node *&p){ 44 if (p == null){ 45 p = newnode(x); return; 46 } 47 p->s++; if (x == p->v) p->w++; 48 else{ 49 int d = x > p->v; 50 ins(x,p->ch[d]); 51 if (p->ch[d]->r < p->r) rotate(p,d^1); 52 } 53 } 54 void del(int x,Node *&p){ 55 if (p == null) return; 56 if (p->v == x){ 57 if (p->w > 1){ 58 p->s--; p->w--; return; 59 } 60 if (p->ch[0] != null && p->ch[1] != null){ 61 int d = p->ch[0]->r > p->ch[1]->r; 62 rotate(p,d); del(x,p->ch[d]); 63 } 64 else p = p->ch[0] == null ? p->ch[1] : p->ch[0]; 65 } 66 else{ 67 int d = x > p->v; p->s--; 68 del(x,p->ch[d]); 69 } 70 if (p != null) p->maintain(); 71 } 72 int get_smaller(int x){ 73 int ans = 0; 74 for(Node *p = root; p != null;){ 75 if (x > p->v) ans += p->ch[0]->s + p->w, p = p->ch[1]; 76 else if (x == p->v){ 77 ans += p->ch[0]->s; break; 78 } 79 else p = p->ch[0]; 80 } 81 return ans; 82 } 83 int get_bigger(int x){ 84 int ans = 0; 85 for(Node *p = root; p != null;){ 86 if (x < p->v) ans += p->ch[1]->s + p->w, p = p->ch[0]; 87 else if (x == p->v){ 88 ans += p->ch[1]->s; break; 89 } 90 else p = p->ch[1]; 91 } 92 return ans; 93 } 94 }treap[maxn<<2]; 95 inline int query(int l,int r,int x,bool type){ 96 if (l > r) return 0; 97 int ret = 0; l += M; r += M; 98 if (l == r) return type ? treap[l].get_bigger(x) : treap[l].get_smaller(x); 99 if (!type) ret += treap[l].get_smaller(x) + treap[r].get_smaller(x); 100 else ret += treap[l].get_bigger(x) + treap[r].get_bigger(x); 101 if (!type){ 102 for(; l^r^1; l>>=1, r>>=1){ 103 if (!(l&1)) ret += treap[l^1].get_smaller(x); 104 if (r&1) ret += treap[r^1].get_smaller(x); 105 } 106 } 107 else{ 108 for(; l^r^1; l>>=1, r>>=1){ 109 if (!(l&1)) ret += treap[l^1].get_bigger(x); 110 if (r&1) ret += treap[r^1].get_bigger(x); 111 } 112 } 113 return ret; 114 } 115 int main(){ 116 n = read(); for(M = 1; M < n; M <<= 1); M--; 117 rep(i,1,n){ 118 h[i] = read(); 119 for(int j=i+M; j>1; j>>=1) 120 if (j&1) ans += treap[j^1].get_bigger(h[i]); 121 for(int j=i+M; j; j>>=1) 122 treap[j].ins(h[i],treap[j].root); 123 } 124 printf("%d\n",ans); 125 m = read(); 126 rep(i,1,m){ 127 l = read(); r = read(); 128 if (l > r) swap(l,r); 129 if (l == r){ 130 printf("%d\n",ans); continue; 131 } 132 ans += query(l+1,r-1,h[l],1) + query(l+1,r-1,h[r],0); 133 ans -= query(l+1,r-1,h[l],0) + query(l+1,r-1,h[r],1); 134 for(int j=l+M; j; j>>=1) treap[j].ins(h[r],treap[j].root); 135 for(int j=l+M; j; j>>=1) treap[j].del(h[l],treap[j].root); 136 for(int j=r+M; j; j>>=1) treap[j].ins(h[l],treap[j].root); 137 for(int j=r+M; j; j>>=1) treap[j].del(h[r],treap[j].root); 138 if (h[l] < h[r]) ans++; else if (h[l] > h[r]) ans--; 139 swap(h[l],h[r]); 140 printf("%d\n",ans); 141 } 142 return 0; 143 }