CodeForces 785E Anton and Permutation (分块)
来源:互联网 发布:淘宝最诚信的邮票商家 编辑:程序博客网 时间:2024/05/18 13:10
题意:初始是一个1-n的长度为n的有序数组,现在q次询问,每次询问交换a[l], a[r] 并且输出交换后整个数组有多少对逆序对(每次循环具有后效性)。1 ≤ n ≤ 200 000, 1 ≤ q ≤ 50 000
思路:第一个分块题,看到一篇讲的非常好的博客(戳这里),我写的话肯定没他写的好,,,
粘下他的思路吧:
当交换a[l]和a[r]时。讨论区间为(l,r),那么
所以问题就转化为如何求一个连续区间
考虑分块。且块中元素保持有序,便于二分查询。
1.若l==r,则ans不变。
2.若l和r属于同一个块,可以
3.若l和r不属于同一个块,先扫描区间
最坏情况下询问复杂度应该是
这道题可以使用分块查询的原因是每次更新时,最多只需要处理2个块,其他块中的信息能够以
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<vector>using namespace std;typedef long long ll;const int maxn = 2e5+5;const int maxsqrt = 505;int a[maxn], L[maxn], R[maxn], n, q, num;vector<int> blk[maxsqrt];void init(){ num = (int)sqrt(n); for(int i = 0; i <= num+1; i++) blk[i].clear(); for(int i = 0; i < n/num; i++) L[i] = num*i, R[i] = num*(i+1); if(n%num) L[n/num] = n-(n%num), R[n/num] = n; for(int i = 0; i < n; i++) a[i] = i, blk[i/num].push_back(i);}int main(void){ while(cin >> n >> q) { init(); ll ans = 0; while(q--) { int l, r; scanf("%d%d", &l, &r); l--, r--; if(l == r) { printf("%I64d\n", ans); continue ; } if(l > r) swap(l, r); int idl = l/num, idr = r/num; for(int i = idl+1; i < idr; i++) { int p = lower_bound(blk[i].begin(), blk[i].end(), a[l])-blk[i].begin(); ans -= p; ans += blk[i].size()-p; p = lower_bound(blk[i].begin(), blk[i].end(), a[r])-blk[i].begin(); ans += p; ans -= blk[i].size()-p; } for(int i = l+1; i < R[idl] && i < r; i++) { if(a[i] > a[l]) ans++; else ans--; if(a[i] > a[r]) ans--; else ans++; } for(int i = L[idr]; i < r && i > l; i++) { if(a[i] > a[l]) ans++; else ans--; if(a[i] > a[r]) ans--; else ans++; } if(idl < idr) { blk[idl].erase(lower_bound(blk[idl].begin(), blk[idl].end(), a[l])); blk[idl].insert(lower_bound(blk[idl].begin(), blk[idl].end(), a[r]), a[r]); blk[idr].erase(lower_bound(blk[idr].begin(), blk[idr].end(), a[r])); blk[idr].insert(lower_bound(blk[idr].begin(), blk[idr].end(), a[l]), a[l]); } if(a[l] < a[r]) ans++; else ans--; swap(a[l], a[r]); printf("%I64d\n", ans); } } return 0;}
阅读全文
1 0
- CodeForces 785E Anton and Permutation 分块
- codeforces 785 E. Anton and Permutation(分块)
- CodeForces 785E Anton and Permutation (分块)
- Codefores 785E Anton and Permutation(分块)
- codeforces 785E. Anton and Permutation
- codeforces 785 E. Anton and Permutation
- Codeforces Round #404 (Div. 2) -- E. Anton and Permutation(分块xjb 搞)
- Codeforces Round #404 (Div. 2)E. Anton and Permutation(分块)
- Codeforces Round #404 (Div. 2):E. Anton and Permutation(分块)
- Codeforces-785E-Anton and Permutation(分块区间查询,动态查询[l,r]内小于某个值的元素个数)
- Codeforces Round #404 (Div. 2) E. Anton and Permutation(分块+二分)
- E. Anton and Permutation (树状数组+主席树)
- CodeForces 734 E.Anton and Tree(dfs)
- Codeforces-734E Anton and Tree(树的直径)
- Codeforces 584E Anton and Ira
- CodeForces 584E Anton and Ira
- 【25.00%】【codeforces 584E】Anton and Ira
- CodeForces 734E - Anton and Tree
- HDU 5213 Lucky(莫队+容斥)
- 关于mac上没有include文件以及没有mysql.h的解决方案
- RecyclerView 中 textView 省略号相关
- Java设计模式之策略模式
- python opencv入门 直方图反向投影(24)
- CodeForces 785E Anton and Permutation (分块)
- Unity2017+Easytouch5双摇杆控制角色&&视角&&animation动画[新手向]
- MyBatis Generator详解
- 装修日志
- POJ 3526 The Teacher’s Side of Math 高斯消元
- 多校6 HDU-6098 Inversion 水题以及神奇的代码操作
- 2017.08.10
- laravel 自定义全局函数
- 【Leetcode】【python】Roman to Integer