RT

传送门


首先可以看成倒着插入,求逆序对数

每个数分配时间(注意每个数都要一个时间)$t$,$x$位置,$y$数值

$CDQ(l,r)$时归并排序$x$

然后用$[l,mid]$的加入更新$[mid+1,r]$的查询(其实每个数就是一个插入一个查询)

这里就是前后求逆序对,用树状数组

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstring>
  5. using namespace std;
  6. typedef long long ll;
  7. const int N=2e5+;
  8. inline int read(){
  9. char c=getchar();int x=,f=;
  10. while(c<''||c>''){if(c=='-')f=-;c=getchar();}
  11. while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
  12. return x*f;
  13. }
  14. int n,m;
  15. int mp[N];
  16. struct Operation{
  17. int t,x,y;
  18. Operation(){}
  19. Operation(int t,int id,int v):t(t),x(id),y(v){}
  20. bool operator <(const Operation &r)const{
  21. return x==r.x ? y<r.y : x<r.x;
  22. }
  23. }a[N],t[N];
  24. inline bool cmpTime(const Operation &a,const Operation &b){
  25. return a.t==b.t ? a.x<b.x : a.t<b.t;
  26. }
  27. int c[N];
  28. inline int lowbit(int x){return x&-x;}
  29. inline void add(int p,int v){for(;p<=n;p+=lowbit(p)) c[p]+=v;}
  30. inline int sum(int p){
  31. int re=;
  32. for(;p;p-=lowbit(p)) re+=c[p];
  33. return re;
  34. }
  35. ll ans[N];
  36. void CDQ(int l,int r){
  37. if(l==r) return;
  38. int mid=(l+r)>>;
  39. CDQ(l,mid);CDQ(mid+,r);
  40. int i=l,j=mid+,p=l;
  41. while(i<=mid||j<=r){
  42. if(j>r||(i<=mid&&a[i]<a[j])) add(a[i].y,),t[p++]=a[i++];
  43. else ans[a[j].t]+=sum(n)-sum(a[j].y),t[p++]=a[j++];
  44. }
  45. for(int i=l;i<=mid;i++) add(a[i].y,-);
  46. for(int i=l;i<=r;i++) a[i]=t[i];
  47. for(int i=r;i>=l;i--){
  48. if(a[i].t<=mid) add(a[i].y,);
  49. else ans[a[i].t]+=sum(a[i].y);
  50. }
  51. for(int i=l;i<=r;i++) if(a[i].t<=mid) add(a[i].y,-);
  52. }
  53. int main(){
  54. //freopen("inverse.in","r",stdin);
  55. //freopen("inverse.out","w",stdout);
  56. n=read();m=read();
  57. for(int i=;i<=n;i++) a[i]=Operation(,i,read()),mp[a[i].y]=i;
  58. int Tim=n;
  59. for(int i=;i<=m;i++) a[mp[read()]].t=Tim--;
  60. for(int i=;i<=n;i++) if(!a[i].t) a[i].t=Tim--;
  61. sort(a+,a++n,cmpTime);
  62. //for(int i=1;i<=10;i++) printf("hi %d %d %d\n",i,a[i].t,a[i].y);
  63. CDQ(,n);
  64. //for(int i=1;i<=10;i++) printf("ans %d %d\n",i,ans[i]);
  65. for(int i=;i<=n;i++) ans[i]+=ans[i-];
  66. for(int i=n;i>=n-m+;i--) printf("%lld\n",ans[i]);
  67. }

【update 2017-03-17】

前两天学到了删除的姿势,逆序对问题的删除操作不用时间倒流也可以,直接减去它形成的逆序对数并且在树状数组中删除就可以了

虽然慢一些但是清晰多了

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstring>
  5. using namespace std;
  6. typedef long long ll;
  7. const int N=2e5+;
  8. inline int read(){
  9. char c=getchar();int x=,f=;
  10. while(c<''||c>''){if(c=='-')f=-;c=getchar();}
  11. while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
  12. return x*f;
  13. }
  14.  
  15. int n,Q,a[N],pos[N],x;
  16. int m,tim;
  17. struct meow{
  18. int t,x,y,type,qid;
  19. meow(){}
  20. meow(int a,int b,int c,int d,int e=):t(a),x(b),y(c),type(d),qid(e){}
  21. bool operator <(const meow &r) const{
  22. return x==r.x ? y<r.y : x<r.x;
  23. }
  24. }q[N],t[N];
  25. ll ans[N];
  26.  
  27. int c[N];
  28. inline void add(int p,int v) {for(;p<=n;p+=(p&-p)) c[p]+=v;}
  29. inline int sum(int p) {int re=; for(;p;p-=(p&-p)) re+=c[p]; return re;}
  30.  
  31. void CDQ(int l,int r){
  32. if(l==r) return;
  33. int mid=(l+r)>>;
  34. for(int i=l;i<=r;i++){
  35. if(q[i].t<=mid) add(q[i].y,q[i].type);
  36. else ans[q[i].qid]+= q[i].type*( sum(n)-sum(q[i].y) );
  37. }
  38. for(int i=l;i<=r;i++) if(q[i].t<=mid) add(q[i].y,-q[i].type);
  39.  
  40. for(int i=r;i>=l;i--){
  41. if(q[i].t<=mid) add(q[i].y,q[i].type);
  42. else ans[q[i].qid]+= q[i].type*sum(q[i].y-);
  43. }
  44. for(int i=l;i<=r;i++) if(q[i].t<=mid) add(q[i].y,-q[i].type);
  45.  
  46. int p1=l,p2=mid+;
  47. for(int i=l;i<=r;i++){
  48. if(q[i].t<=mid) t[p1++]=q[i];
  49. else t[p2++]=q[i];
  50. }
  51. for(int i=l;i<=r;i++) q[i]=t[i];
  52. CDQ(l,mid); CDQ(mid+,r);
  53. }
  54.  
  55. int main(){
  56. freopen("in","r",stdin);
  57. n=read(); Q=read();
  58. for(int i=;i<=n;i++) a[i]=read(), pos[a[i]]=i, q[++m]=meow(++tim, i, a[i], , );
  59.  
  60. for(int i=;i<=Q;i++) x=read(), q[++m]=meow(++tim, pos[x], x, -, i);
  61. sort(q+, q++m);
  62. CDQ(,m);
  63. for(int i=;i<=Q;i++) ans[i]+=ans[i-],printf("%lld\n",ans[i-]);
  64. }

BZOJ 3295: [Cqoi2011]动态逆序对 [CDQ分治]的更多相关文章

  1. BZOJ 3295 [Cqoi2011]动态逆序对 ——CDQ分治

    时间.位置.数字为三个属性. 排序时间,CDQ位置,树状数组处理数字即可. #include <cstdio> #include <cstring> #include < ...

  2. Bzoj 3295: [Cqoi2011]动态逆序对 分块,树状数组,逆序对

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2886  Solved: 924[Submit][Stat ...

  3. [BZOJ3295][Cqoi2011]动态逆序对 CDQ分治&树套树

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MB Description 对于序列A,它的逆序对数定义为满足i<j,且 ...

  4. bzoj3295: [Cqoi2011]动态逆序对(cdq分治+树状数组)

    3295: [Cqoi2011]动态逆序对 题目:传送门 题解: 刚学完cdq分治,想起来之前有一道是树套树的题目可以用cdq分治来做...尝试一波 还是太弱了...想到了要做两次cdq...然后伏地 ...

  5. BZOJ3295 [Cqoi2011]动态逆序对 —— CDQ分治

    题目链接:https://vjudge.net/problem/HYSBZ-3295 3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 1 ...

  6. BZOJ 3295: [Cqoi2011]动态逆序对

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3865  Solved: 1298[Submit][Sta ...

  7. 【BZOJ3295】[Cqoi2011]动态逆序对 cdq分治

    [BZOJ3295][Cqoi2011]动态逆序对 Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依 ...

  8. bzoj 3295 [Cqoi2011]动态逆序对(cdq分治,BIT)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3295 [题意] n个元素依次删除m个元素,求删除元素之前序列有多少个逆序对. [思路] ...

  9. bzoj 3295: [Cqoi2011]动态逆序对(树套树 or CDQ分治)

    Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计 ...

随机推荐

  1. Logger之Logger.getLogger(CLass)技巧代替system.out.print

    ---恢复内容开始--- 尊重原创:http://www.cnblogs.com/zxf330301/p/5876117.html 之前一直在使用System.out.println()来调试.但是用 ...

  2. Linux学习之XShell与虚拟机的连接

    最近在慕课网上学习Linux视频,记录一下解决问题的方法和过程. 实验软件环境: 虚拟机软件Vmware Workstation10.0.虚拟机系统CentOS 6.3(32位).XShell 5.0 ...

  3. 调用webService的几种方式

    转自:http://blog.csdn.net/u011165335/article/details/51345224 一.概览 方式1: HttpClient:可以用来调用webservie服务,也 ...

  4. 使用setTimeout实现setInterval

    setInterval = () =>{ console.log(1) //使用递归 setTimeout(setInterval,1000); }; setInterval()

  5. 如何动态修改网页的标题(title)?

    有时候我们需要复用一个页面,但是又希望他们拥有各自的标题,这时候就需要动态的去更改页面的title了,不然所有页面都是一个标题. 这时候就会想到使用js或jQuery去实现了. 1.js方式. 首先, ...

  6. css3渐变之线性渐变

    css3定义了两种类型的渐变,即线性渐变和径向渐变.这里我要说的是线性渐变. 为了创建一个线性渐变,你必须至少定义两种颜色结点.颜色结点即你想要呈现平稳过渡的颜色.同时,你也可以设置一个起点和一个方向 ...

  7. AMD规范学习笔记

    背景 NodeJS的一套比较简洁 Moudles 规范, 使得在服务器端的模块化变得更加简单.很长一段时间,很多公司或者项目都有自己的一套模块化机制, 却未能形成一套统一的标准, NodeJS的Mou ...

  8. ECharts插件的使用

    ECharts插件:官网下载echarts.js开发者可以选择源码.下载地址:http://echarts.baidu.com/download.html 下载之后,echarts.js放在js文件夹 ...

  9. CSS3 background-size图片自适应

    http://www.html5cn.com.cn/css3/2013-04-21/267.html background-size属性和background-origin属性.background- ...

  10. Asp.net Core 跨域配置

    一般情况WebApi都是跨域请求,没有设置跨域一般会报以下错误 No 'Access-Control-Allow-Origin' header is present on the requested ...