bzoj 3295 动态逆序对 CDQ分治
来源:互联网 发布:淘宝源码 编辑:程序博客网 时间:2024/05/16 13:22
每删除一个数对答案的影响是 前面比他大的数的个数+后面比他小的数的个数。问题变成了插入一个数并求出前面有多少数比他大(后面小的数可以用同样方法求)。
首先这可以用一个二维数据结构做。
CDQ分治的强大之处在于它能够压掉一维。它的主要思想是把操作分为两部分,计算前半部分修改对后半部分询问影响,然后递归处理两部分。
我这个代码写的太丑了,调了一天,,,还不如去写树套树>_<。
#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#define maxn 200005#define LL long longusing namespace std;int a[maxn],pos[maxn];int q[maxn];LL ans[maxn];struct BT{ LL c[maxn];int N; int lowbit(int x){return (x&(-x));} void add(int x,int d) { for(;x<=N;x+=lowbit(x)) c[x]+=d; } LL ask(int x) { LL ans=0; for(;x>0;x-=lowbit(x))ans+=c[x]; return ans; }}B;int n,m;struct SZS{ int val,id;}L[maxn],R[maxn];bool cmps(SZS A,SZS B){ return A.val<B.val;}void solve(int l,int r){ if(l==r) return ; int mid=l+r>>1; for(int i=l;i<=mid;i++) L[i-l+1].val=q[i],L[i-l+1].id=i; for(int i=mid+1;i<=r;i++)R[i-mid].val=q[i],R[i-mid].id=i; int len1=mid-l+1,len2=r-mid; sort(L+1,L+len1+1,cmps);sort(R+1,R+len2+1,cmps); int H1=1,H2=1; while(H1<=len1||H2<=len2) { if(H2>len2||(H1<=len1&&L[H1].val<R[H2].val)) B.add(a[L[H1++].val],1); else ans[R[H2].id]+=B.ask(n)-B.ask(a[R[H2].val]),H2++; } for(int i=1;i<=len1;i++) B.add(a[L[i].val],-1); solve(l,mid);solve(mid+1,r);}bool use[maxn];int tmp[maxn];LL ANS;void init(){ memset(use,0,sizeof(use)); for(int i=1;i<=m;i++) use[q[i]]=1; for(int i=1;i<=n;i++) tmp[i]=0; for(int i=1;i<=n;i++) if(!use[i]) { ANS+=B.ask(n)-B.ask(a[i]); B.add(a[i],1); } else tmp[i]=B.ask(n)-B.ask(a[i]); for(int i=1;i<=n;i++) if(!use[i]) B.add(a[i],-1); for(int i=1;i<=m;i++) ans[i]+=tmp[q[i]];}int main(){ int x; scanf("%d%d",&n,&m); B.N=n; for(int i=1;i<=n;i++) scanf("%d",&a[i]),pos[a[i]]=i; for(int i=1;i<=m;i++) scanf("%d",&x),q[i]=pos[x]; for(int i=1;i<=m/2;i++) swap(q[i],q[m-i+1]); init(); solve(1,m);LL P=ANS; for(int i=1;i<=n/2;i++)swap(a[i],a[n-i+1]); for(int i=1;i<=m;i++) q[i]=n-q[i]+1; for(int i=1;i<=n;i++) a[i]=n-a[i]+1; init(); solve(1,m); for(int i=1;i<=m;i++) P+=ans[i]; for(int i=m;i>=1;i--) { printf("%lld\n",P); P-=ans[i]; } return 0;}
1 0
- BZOJ 3295 动态逆序对 CDQ分治
- bzoj 3295 动态逆序对 CDQ分治
- BZOJ 3295 动态逆序对 CDQ分治
- BZOJ 3295 动态逆序对(CDQ分治)
- bzoj 3295: [Cqoi2011]动态逆序对 【cdq分治】
- bzoj 3295: [Cqoi2011]动态逆序对 cdq分治+树状数组
- BZOJ 3295 [Cqoi2011] 动态逆序对 CDQ分治题解
- 3295: [Cqoi2011]动态逆序对 CDQ分治
- bzoj 3295: [Cqoi2011]动态逆序对 (CDQ分治+树状数组)
- [BZOJ3295] [Cqoi2011]动态逆序对 && CDQ分治
- 【CDQ分治】[CQOI2011][NKOJ2041]动态逆序对
- 【cdq分治】[HYSBZ/BZOJ3295]动态逆序对
- 【bzoj3295】动态逆序对 CDQ分治
- CQOI2011动态逆序对--cdq分治
- [BZOJ3295]动态逆序对CDQ分治
- [BZOJ3295] [Cqoi2011]动态逆序对 (树套树)or(CDQ分治)
- 【BZOJ3295】动态逆序对,CDQ分治/BIT套权值线段树
- CDQ分治——BZOJ3295/Luogu3157 [CQOI2011]动态逆序对
- TabLayout的简单使用
- 一种近乎完美的加密算法:扩散加密算法
- Java常见开发规范
- 黑盒测试用例设计方法
- 链表面试题--合并两个有序的链表
- bzoj 3295 动态逆序对 CDQ分治
- MySQL:ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails
- c3p0连接池基本配置mysql和oracle
- codeforces 767a
- 鸟哥的服务器《十四》OpenSSL
- STL源码剖析 --vector
- 关于maven项目中pom.xml依赖的scope的作用范围
- PHP排序函数-根据指定字段将数组排序
- git checkout到历史某个版本