Infinite Inversions CodeForces - 540E (树状数组+离散化)
2017-09-29 13:05
513 查看
题目链接
题目大意,在一串无穷的1,2,3…n的串值,有k次操作,每次操作给出两个数a,b,即把坐标a和坐标b的值交换,问最后有多少个逆序对,0<=k<=105,a和b在int范围内
分析:问题的关键是,操作次数相对与整个序列是比较稀疏的,也就是说会有许多连续的数串 ,我们就是把这些连续的数串缩微一个点,而点的权值即为这个数串的数量,用离散化来处理,最后就会转化成一般的形式的统计逆序对个数。
题目大意,在一串无穷的1,2,3…n的串值,有k次操作,每次操作给出两个数a,b,即把坐标a和坐标b的值交换,问最后有多少个逆序对,0<=k<=105,a和b在int范围内
分析:问题的关键是,操作次数相对与整个序列是比较稀疏的,也就是说会有许多连续的数串 ,我们就是把这些连续的数串缩微一个点,而点的权值即为这个数串的数量,用离散化来处理,最后就会转化成一般的形式的统计逆序对个数。
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> using namespace std; struct node { int l,r; }sw[100005];//存交换 int id[400005];//离散化 int f[400005];//每个离散化后的点的权值 int cnt=0; int total=0; int index[400005]; int c[400005]; int getInd(int x)//二分找离散后的点 { int l=0,r=total-1; int mid; while(l<=r) { mid=(l+r)>>1; if(id[mid]==x) return mid+1; if(id[mid]>x) r=mid-1; else l=mid+1; } } int lowBit(int x) { return x&-x; } int sum(int x) { int ans=0; while(x>0) { ans+=c[x]; x-=lowBit(x); } return ans; } void change(int x,int p) { while(x<=total) { c[x]+=p; x+=lowBit(x); } } int main() { int n; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d%d",&sw[i].l,&sw[i].r); index[cnt++]=sw[i].l; index[cnt++]=sw[i].r;//先记录所有离散的点 } sort(index,index+cnt); int num=unique(index,index+cnt)-index;//排序去重 if(index[0]!=1) id[total]=1,f[total+1]=index[0< 4000 /span>]-1,total++; id[total]=index[0],f[total+1]=1,total++; for(int i=1;i<num;i++) { if(index[i]-index[i-1]>1) id[total]=index[i-1]+1,f[total+1]=index[i]-index[i-1]-1,total++; id[total]=index[i],f[total+1]=1,total++; }//把点和点的线段都离散化为点,并维护权值,因为这里id的数组是从0开始的,但实际上是从1开始的,所有只要加1,增加一个单位的偏移量即可 for(int i=1;i<=total;i++) index[i]=i;//一开始从小到大有序,这里是第二次使用index数组,只是为了省空间,因为前面的index已经发挥作用了,可以复用... for(int i=0;i<n;i++) { int l=getInd(sw[i].l); int r=getInd(sw[i].r); int temp=index[l]; index[l]=index[r]; index[r]=temp; }//模拟交换 long long ans=0;//不用long long就是wa for(int i=1;i<=total;i++) { ans+=(long long)f[index[i]]*(sum(total)-sum(index[i])); change(index[i],f[index[i]]); } printf("%lld\n",ans); return 0; }
相关文章推荐
- Educational Codeforces Round 10 D. Nested Segments 离散化+树状数组
- CF Educational Codeforces Round 10 D. Nested Segments 离散化+树状数组
- Educational Codeforces Round 10D 离散化+树状数组
- sgu 180 - Inversions (离散化+树状数组)
- Codeforces Round #425 (Div. 2) Problem D Misha, Grisha and Underground (Codeforces 832D) - 树链剖分 - 树状数组
- Educational Codeforces Round 8 E. Zbazi in Zeydabad 树状数组
- Educational Codeforces Round 23 F. MEX Queries 离散化+线段树
- codeforces gym-101745 C-Infinite Graph Game 分块
- Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake(离散化+线段树)
- Codeforces Round 261 Div.2 D Pashmak and Parmida's problem --树状数组
- J - Pashmak and Parmida's problem CodeForces - 459D(思维优化+树状数组)
- Codeforces Gym 100269F Flight Boarding Optimization 树状数组维护dp
- CodeForces 540E - Infinite Inversions(离散化+树状数组)
- Codeforces Round #182 (Div. 1) Yaroslav and Divisors(离线+树状数组)
- Cinema CodeForces - 670C (map,一维坐标离散化,排序)
- Infinite Maze CodeForces - 197D
- Codeforces Gym 100733J Summer Wars 线段树,区间更新,区间求最大值,离散化,区间求并
- Educational Codeforces Round 7 A. Infinite Sequence 水题
- Codeforces Round #442 (Div. 2) 877 F - Ann and Books 莫队算法 离散化
- Codeforces Round #442 (Div. 2) F. Ann and Books 莫队,离散化