[国家集训队]排队 [cdq分治]
题面
和动态逆序对那道题没有什么区别
把一个交换换成两个删除和两个插入
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
const int N = 1e5 + 5;
const double eps = 1e-9;
const int inf = 0x3f3f3f3f;
typedef pair<int, int> PII;
typedef pair<double, int> PDI;
struct Node{
int x, y, z, d, cnt;
}node[N];
bool rule_yzx(Node x, Node y){
if(x.y != y.y) return x.y < y.y;
if(x.z != y.z) return x.z < y.z;
return x.x < y.x;
}
int n, m, nsize, a[N], b[N];
int tim, dfn[N];
long long ans[N];
struct BIT{
int w[N];
void ins(int x, int d){while(x<=n){w[x] += d; x += x & -x;}}
int qry(int x){int res = 0; while(x){res += w[x]; x -= x & -x;}return res;}
void print(){for(int i = 1; i <= n; ++i) printf("%d", w[i]); printf("\n");}
}bit;
inline void add(int x1, int x2, int x3, int x4){
++nsize;
node[nsize].x = x1, node[nsize].y = x2, node[nsize].z = x3, node[nsize].d = x4;
}
void cdq(int L, int R){
if(L == R) return ;
int mid = L + ((R - L) >> 1);
cdq(L, mid); cdq(mid + 1, R);
sort(node + L, node + mid + 1, rule_yzx);
sort(node + mid + 1, node + R + 1, rule_yzx);
int j = L;
for(int i = mid + 1; i <= R; ++i){
while(j <= mid && node[j].y <= node[i].y){
bit.ins(node[j].z, node[j].d); ++j;
}
node[i].cnt += node[i].d * (bit.qry(n) - bit.qry(node[i].z));
}
//printf("L %d R %d\n", L, R);
//bit.print();
while(j > L){--j; bit.ins(node[j].z, -node[j].d);}
j = mid;
for(int i = R; i >= mid + 1; --i){
while(j >= L && node[j].y >= node[i].y){
bit.ins(node[j].z, node[j].d); --j;
}
node[i].cnt += node[i].d * bit.qry(node[i].z - 1);
}
while(j < mid){++j; bit.ins(node[j].z, -node[j].d);}
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; ++i){
scanf("%d", &a[i]); b[i] = a[i];
}
sort(b + 1, b + n + 1);
for(int i = 1; i <= n; ++i){
a[i] = (lower_bound(b + 1, b + n + 1, a[i]) - b);
add(0, i, a[i], 1);
//printf("%d %d %d\n", node[i].x, node[i].y, node[i].z);
}
scanf("%d", &m);
for(int i = 1, x, y; i <= m; ++i){
scanf("%d%d", &x, &y);
add(++tim, x, a[x], -1);
add(++tim, y, a[y], -1);
swap(a[x], a[y]);
add(++tim, x, a[x], 1);
add(++tim, y, a[y], 1);
dfn[i] = tim;
}
//for(int i = 1; i <= nsize; ++i) printf("%d %d %d\n", node[i].x, node[i].y, node[i].z);
//已经是升序了
cdq(1, nsize);
for(int i = 1; i <= nsize; ++i){
//printf("%d %d %d %d\n", node[i].x, node[i].y, node[i].z, node[i].cnt);
ans[node[i].x] += node[i].cnt;
}
for(int i = 1; i <= tim; ++i) ans[i] += ans[i - 1];
for(int i = 0; i <= m; ++i) printf("%d\n", ans[dfn[i]]);
system("PAUSE");
return 0;
}