bzoj 2141 : 排队 分块

题目链接

 

2141: 排队

Time Limit: 4 Sec  Memory Limit: 259 MB
Submit: 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

Sample Output

1
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 }

 

posted on 2016-03-10 20:28  yohaha  阅读(215)  评论(0编辑  收藏  举报

导航