bzoj 2141 : 排队 分块
2141: 排队
Time Limit: 4 Sec Memory Limit: 259 MBSubmit: 1169 Solved: 465
[Submit][Status][Discuss]
Description
排排坐,吃果果,生果甜嗦嗦,大家笑呵呵。你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和。红星幼儿园的小朋友们排起了长长地队伍,准备吃果果。不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观。设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为:满足ihj的(i,j)数量。幼儿园阿姨每次会选出两个小朋友,交换他们的位置,请你帮忙计算出每次交换后,序列的杂乱程度。为方便幼儿园阿姨统计,在未进行任何交换操作时,你也应该输出该序列的杂乱程度。
Input
第一行为一个正整数n,表示小朋友的数量;第二行包含n个由空格分隔的正整数h1,h2,…,hn,依次表示初始队列中小朋友的身高;第三行为一个正整数m,表示交换操作的次数;以下m行每行包含两个正整数ai和bi¬,表示交换位置ai与位置bi的小朋友。
Output
输出文件共m行,第i行一个正整数表示交换操作i结束后,序列的杂乱程度。
Sample Input
【样例输入】
3
130 150 140
2
2 3
1 3
3
130 150 140
2
2 3
1 3
Sample Output
1
0
3
0
3
每次交换两个数, 求交换之后的逆序对的个数。
思路: 我们分块来做, 如果要交换的两个数x, y在同一块里, 那么就暴力计算。 否则的话, 暴力计算x+1到x这个块的最右边, 和y-1到y这个块的最左边, 两个块中间的块用二分查找来计算。
弱智错误查了一个小时...
1 #include <iostream> 2 #include <vector> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #include <cmath> 7 #include <map> 8 #include <set> 9 #include <string> 10 #include <queue> 11 #include <stack> 12 #include <bitset> 13 using namespace std; 14 #define pb(x) push_back(x) 15 #define ll long long 16 #define mk(x, y) make_pair(x, y) 17 #define lson l, m, rt<<1 18 #define mem(a) memset(a, 0, sizeof(a)) 19 #define rson m+1, r, rt<<1|1 20 #define mem1(a) memset(a, -1, sizeof(a)) 21 #define mem2(a) memset(a, 0x3f, sizeof(a)) 22 #define rep(i, n, a) for(int i = a; i<n; i++) 23 #define fi first 24 #define se second 25 typedef pair<int, int> pll; 26 const double PI = acos(-1.0); 27 const double eps = 1e-8; 28 const int mod = 1e9+7; 29 const int inf = 1061109567; 30 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; 31 const int maxn = 2e4+5; 32 int a[maxn], b[maxn], c[maxn], sum[maxn], l[maxn], r[maxn], belong[maxn]; 33 int block, cnt, n, ans; 34 int lowbit(int x) { 35 return x&(-x); 36 } 37 void update(int x) { 38 for(int i = x; i<=n; i+=lowbit(i)) { 39 sum[i]++; 40 } 41 } 42 int query(int x) { 43 int ret = 0; 44 for(int i = x; i>0; i-=lowbit(i)) { 45 ret += sum[i]; 46 } 47 return ret; 48 } 49 void rebuild(int x) { 50 for(int i = l[x]; i<=r[x]; i++) 51 b[i] = a[i]; 52 sort(b+l[x], b+r[x]+1); 53 } 54 void pre() { 55 for(int i = n; i>0; i--) { 56 ans += query(a[i]-1); 57 update(a[i]); 58 } 59 for(int i = 1; i<=cnt; i++) { 60 rebuild(i); 61 } 62 } 63 void cmp(int x, int y) { 64 if(x>y) 65 ans++; 66 if(x<y) //不要写else...可能相等 67 ans--; 68 } 69 void solve(int x, int y) { 70 if(a[x]>a[y]) 71 ans--; 72 if(a[x]<a[y]) //不要写else!! 73 ans++; 74 if(belong[x] == belong[y]) { 75 for(int i = x+1; i<y; i++) { 76 cmp(a[i], a[x]); 77 cmp(a[y], a[i]); 78 } 79 } else { 80 for(int i = x+1; i<=r[belong[x]]; i++) { 81 cmp(a[i], a[x]); 82 cmp(a[y], a[i]); 83 } 84 for(int i = l[belong[y]]; i<y; i++) { 85 cmp(a[i], a[x]); 86 cmp(a[y], a[i]); 87 } 88 for(int i = belong[x]+1; i<belong[y]; i++) { 89 ans -= lower_bound(b+l[i], b+r[i]+1, a[x])-b-1-l[i]; 90 ans += lower_bound(b+l[i], b+r[i]+1, a[y])-b-1-l[i]; 91 ans -= r[i] - (upper_bound(b+l[i], b+r[i]+1, a[y])-b-l[i]); 92 ans += r[i] - (upper_bound(b+l[i], b+r[i]+1, a[x])-b-l[i]); 93 } 94 } 95 swap(a[x], a[y]); 96 rebuild(belong[x]); 97 rebuild(belong[y]); 98 } 99 int main() 100 { 101 int m; 102 cin>>n; 103 block = sqrt(1.0*n); 104 if(n%block) 105 cnt = n/block+1; 106 else 107 cnt = n/block; 108 for(int i = 1; i<=cnt; i++) { 109 l[i] = (i-1)*block+1; 110 r[i] = i*block; 111 } 112 r[cnt] = n; 113 for(int i = 1; i<=n; i++) { 114 scanf("%d", &a[i]); 115 c[i-1] = a[i]; 116 belong[i] = (i-1)/block+1; 117 } 118 sort(c, c+n); 119 int tmp = unique(c, c+n)-c; 120 for(int i = 1; i<=n; i++) { 121 a[i] = b[i] = lower_bound(c, c+tmp, a[i])-c+1; 122 } 123 pre(); 124 cout<<ans<<endl; 125 cin>>m; 126 while(m--) { 127 int x, y; 128 scanf("%d%d", &x, &y); 129 if(x>y) 130 swap(x, y); 131 solve(x, y); 132 printf("%d\n", ans); 133 } 134 return 0; 135 }