Uva 11990 "Dynamic" Inversion(树状数组 + 数据结构分块)
来源:互联网 发布:出国留学的意义 知乎 编辑:程序博客网 时间:2024/05/20 23:03
题意:给一个1 ~ n的排列,有m次删除操作,问每次删除前该序列有多少逆序对
思路:预处理原来总共有多少逆序对,树状数组即可,求出以每个数为逆序对有多少个,删除的时候,先用剩余的逆序对数减去以该数形成的逆序对数,然后看删除的数有多少与该数形成逆序对,再加回去,可以使用分块的方法,快速查询有多少删除的数与其形成逆序对,每次删除的数加在一个新数组上,对新数组分块查找就行了
#include<cstdio>#include<cstring>#include<algorithm>typedef long long ll;const int maxn = 2 * 1e5 + 10;const int sz = 2345;using namespace std;int block[maxn / sz + 1][sz];int a[maxn], id[maxn];int inv[maxn];int C[maxn];int n, m, d;int query(int l, int r, int v, int op) { if(l > r) return 0; int lb = l / sz, rb = r / sz; int k1 = 0, k2 = 0; if(lb == rb) { for(int i = l; i <= r; i++) { if(a[i] && a[i] < v) k1++; if(a[i] > v) k2++; } } else { for(int i = l; i < (lb + 1) * sz; i++) { if(a[i] && a[i] < v) k1++; if(a[i] > v) k2++; } for(int i = rb * sz; i <= r; i++) { if(a[i] && a[i] < v) k1++; if(a[i] > v) k2++; } for(int b = lb + 1; b < rb; b++) { int c1 = lower_bound(block[b], block[b] + sz, v) - block[b]; int c2 = upper_bound(block[b], block[b] + sz, 0) - lower_bound(block[b], block[b] + sz, 0); k1 += c1 - c2; int ind = upper_bound(block[b], block[b] + sz, v) - block[b]; k2 += sz - ind; } } if(op == 1) return k1; if(op == 2) return k2;}void update(int p, int x) { if(a[p] == x) return ; int old = a[p], pos = 0, *B = &block[p / sz][0]; a[p] = x; while(B[pos] < old) pos++; B[pos] = x; if(x > old) { while(pos < sz - 1 && B[pos] > B[pos + 1]) { swap(B[pos], B[pos + 1]); pos++; } } else { while(pos && B[pos] < B[pos - 1]) { swap(B[pos], B[pos - 1]); pos--; } }}int sum(int *C, int i) { int c = 0; while(i) { c += C[i]; i -= i & -i; } return c;}void update(int *C, int i) { while(i <= n) { C[i]++; i += i & -i; }}int main() { while(scanf("%d %d", &n, &m) != EOF) { memset(inv, 0, sizeof inv); memset(C, 0, sizeof C); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); id[a[i]] = i; } ll tal = 0; for(int i = n; i >= 1; i--) { int g = sum(C, a[i] - 1); tal += g; inv[i] += g; inv[i] += i + g - a[i]; update(C, a[i]); } memset(a, 0, sizeof a); while(m--) { printf("%lld\n",tal); scanf("%d", &d); tal -= inv[id[d]]; tal += query(id[d] + 1, n, d, 1); tal += query(1, id[d] - 1, d, 2); update(id[d], d); } } return 0;}
0 0
- Uva 11990 "Dynamic" Inversion(树状数组 + 数据结构分块)
- [Uva 11990] "Dynamic" Inversion (二维分块)
- uva11990 - ``Dynamic'' Inversion(线段树套树状数组+分块)
- UVA 11990``Dynamic'' Inversion(树套树)
- UVA11990 ``Dynamic'' Inversion (树状数组套平衡树)
- 【UVA, 11990】“Dynamic” Inversion【平方分割n】
- HDU4911-Inversion(树状数组)
- [Uva 11990] "Dynamic" Inversion (CDQ分治入门)
- Uva 11990 ``Dynamic'' Inversion(分桶法+平方分割)
- bzoj2141【分块+树状数组】
- HDU1394Minimum Inversion Number(树状数组)
- Minimum Inversion Number [树状数组]
- hdu 5497 Inversion(树状数组)
- hdu5497 Inversion 树状数组 待补完!!!
- Minimum Inversion Number 树状数组
- 2141: 排队 分块+树状数组
- ZOJ2112 Dynamic Rankings 解题报告【数据结构】【分块】
- spoj 861 SWAPS & uva 11990 "Dynamic'' Inversion(动态维护逆序对)
- 关于GOP与RAP的一些解释
- Java Applet 基础
- n-1位数(字符串)
- Ubuntu16.04 gedit 中文乱码
- 欢迎使用CSDN-markdown编辑器
- Uva 11990 "Dynamic" Inversion(树状数组 + 数据结构分块)
- 继承SlidingFragmentActivity实现侧滑View
- Java 流(Stream)、文件(File)和IO
- cshtm是什么文件?
- 94. Binary Tree Inorder Traversal**
- MatConvNet--Function index
- Java Scanner 类
- 欢迎使用CSDN-markdown编辑器
- Linux下阅读源码工具