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 }
View Code

 

posted on 2016-01-19 21:42  ACMICPC  阅读(272)  评论(0编辑  收藏  举报

导航