题目:

Description

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

Input

输入第一行包含两个整数nm,即初始元素的个数和删除的元素个数。以下n行每行包含一个1到n之间的正整数,即初始排列。以下m行每行一个正整数,依次为每次删除的元素。
 

Output

 
输出包含m行,依次为删除每个元素之前,逆序对的个数。

Sample Input

5 4
1
5
3
4
2
5
1
4
2

Sample Output

5
2
2
1

样例解释
(1,5,3,4,2)(1,3,4,2)(3,4,2)(3,2)(3)。

HINT

N<=100000 M<=50000

Source

题解:

同样的一道三维偏序题,将删除看成倒着插入,从而得出:<插入时间,位置,大小>(<t,a,b>),对于一个组数<t,a,b>,找寻(t>t1,a>a1且b<b1)的数量加到对应的ans[t]中,注意最后将ans叠加起来;

另外要注意在排完t后,a要正着排序求一遍ans然后倒着排序一遍ans,否则ans会少加(想想为什么单纯地求逆序对不用这样)

代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cmath>
  5. #include<ctime>
  6. #include<cctype>
  7. #include<cstring>
  8. #include<string>
  9. #include<algorithm>
  10. using namespace std;
  11. const int N=1e5+;
  12. struct node
  13. {
  14. int t,a,b;
  15. }q[N],temp[N];
  16. int n,m,tree[N],to[N],tag[N],tim;
  17. long long ans[N];
  18. long long Ans;
  19. inline int R()
  20. {
  21. char c;int f=;
  22. for(c=getchar();c<''||c>'';c=getchar());
  23. for(;c<=''&&c>='';c=getchar())
  24. f=(f<<)+(f<<)+c-'';
  25. return f;
  26. }
  27. inline bool cmp(node a,node b)
  28. {
  29. return a.t<b.t;
  30. }
  31. inline bool comp(node a,node b)
  32. {
  33. return a.a<b.a;
  34. }
  35. inline void insert(int u,int v)
  36. {
  37. for(int i=u;i<=n;i+=(i&(-i)))
  38. if(tag[i]!=tim) tag[i]=tim,tree[i]=v;
  39. else tree[i]+=v;
  40. }
  41. inline bool comp2(node a,node b)
  42. {
  43. return a.a>b.a;
  44. }
  45. inline int query(int u)
  46. {
  47. int temp=;
  48. for(int i=u;i;i-=(i&(-i)))
  49. if(tag[i]!=tim) continue;
  50. else temp+=tree[i];
  51. return temp;
  52. }
  53. inline void solve1(int l,int r)
  54. {
  55. if(l==r) return;
  56. int mid=(l+r)/;
  57. solve1(l,mid),solve1(mid+,r);
  58. int i=l,j=mid+,k=l;tim++;
  59. while(i<=mid&&j<=r)
  60. {
  61. if(comp(q[i],q[j]))
  62. {
  63. insert(q[i].b,);
  64. temp[k++]=q[i++];
  65. }
  66. else
  67. {
  68. ans[q[j].t]+=query(n)-query(q[j].b);
  69. temp[k++]=q[j++];
  70. }
  71. }
  72. while(i<=mid) temp[k++]=q[i++];
  73. while(j<=r)
  74. {
  75. ans[q[j].t]+=query(n)-query(q[j].b);
  76. temp[k++]=q[j++];
  77. }
  78. for(j=l;j<=r;j++) q[j]=temp[j];
  79.  
  80. }
  81. inline void solve2(int l,int r)
  82. {
  83. if(l==r) return;
  84. int mid=(l+r)/;
  85. solve2(l,mid),solve2(mid+,r);
  86. int i=l,j=mid+,k=l;tim++;
  87. while(i<=mid&&j<=r)
  88. {
  89. if(comp(q[j],q[i]))
  90. {
  91. insert(q[i].b,);
  92. temp[k++]=q[i++];
  93. }
  94. else
  95. {
  96. ans[q[j].t]+=query(q[j].b);
  97. temp[k++]=q[j++];
  98. }
  99. }
  100. while(i<=mid) temp[k++]=q[i++];
  101. while(j<=r)
  102. {
  103. ans[q[j].t]+=query(q[j].b);
  104. temp[k++]=q[j++];
  105. }
  106. for(j=l;j<=r;j++) q[j]=temp[j];
  107. }
  108. int main()
  109. {
  110. #ifndef ONLINE_JUDGE
  111. //freopen("a.in","r",stdin);
  112. #endif
  113. n=R(),m=R();
  114. for(int i=;i<=n;i++)
  115. {
  116. q[i].a=i,q[i].b=R();
  117. to[q[i].b]=i;
  118. }
  119. int Time=n,a;
  120. for(int i=;i<=m;i++)
  121. {
  122. a=R();q[to[a]].t=Time--;
  123. }
  124. for(int i=;i<=n;i++)
  125. if(!q[i].t) q[i].t=Time--;
  126. sort(q+,q+n+,cmp);
  127. solve1(,n);
  128. sort(q+,q+n+,cmp);
  129. solve2(,n);
  130. for(int i=;i<=n;i++)
  131. Ans+=ans[i];
  132. for(int i=n;i>n-m;i--)
  133. printf("%lld\n",Ans),Ans-=ans[i];
  134. return ;
  135. }

刷题总结——动态逆序对(bzoj3295)的更多相关文章

  1. 【CQOI2011】动态逆序对 BZOJ3295

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

  2. [bzoj3295][Cqoi2011]动态逆序对_主席树

    动态逆序对 bzoj-3295 Cqoi-2011 题目大意:题目链接. 注释:略. 想法:直接建立主席树. 由于是一个一个删除,所以我们先拿建立好的root[n]的权值线段树先把总逆序对求出来,接着 ...

  3. bzoj千题计划146:bzoj3295: [Cqoi2011]动态逆序对

    http://www.lydsy.com/JudgeOnline/problem.php?id=3295 正着删除看做倒着添加 对答案有贡献的数对满足以下3个条件: 出现时间:i<=j 权值大小 ...

  4. 【BZOJ3295】动态逆序对(线段树,树状数组)

    [BZOJ3295]动态逆序对(线段树,树状数组) 题面 Description 对于序列A,它的逆序对数定义为满足iAj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的 ...

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

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

  6. 2018.07.01 BZOJ3295: [Cqoi2011]动态逆序对(带修主席树)

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

  7. BZOJ3295: [Cqoi2011]动态逆序对(树状数组套主席树)

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

  8. bzoj3295 [Cqoi2011]动态逆序对 cdq+树状数组

    [bzoj3295][Cqoi2011]动态逆序对 2014年6月17日4,7954 Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数. ...

  9. bzoj3295 洛谷P3157、1393 动态逆序对——树套树

    题目:bzoj3295 https://www.lydsy.com/JudgeOnline/problem.php?id=3295 洛谷 P3157(同一道题) https://www.luogu.o ...

随机推荐

  1. 在Eclipse上运行Spark(Standalone,Yarn-Client)

    欢迎转载,且请注明出处,在文章页面明显位置给出原文连接. 原文链接:http://www.cnblogs.com/zdfjf/p/5175566.html 我们知道有eclipse的Hadoop插件, ...

  2. Maven常见知识介绍

    1)pom详解 2)pom详解 3)测试 4)插件与生命周期 5)maven生命周期 6)范围依赖

  3. ScriptManager对象的属性

    --<本文属于摘抄> 属性 说明 EnablePageMethods 指定在ASPX页面上定义的公共静态方法是否可以从客户端脚本中作为Web服务方法调用 EnablePartialRend ...

  4. UISearchBar clearButton

    When the searchBar:textDidChange: method of the UISearchBarDelegate gets called because of the user ...

  5. SQLite-表达式

    SQLite -表达式 一个表达式是一个或多个值的组合,运算符和SQL函数,评价一个值. SQL表达式就像公式和都写在查询语言.您还可以使用为特定的数据集查询数据库. 语法: 考虑到SELECT语句的 ...

  6. 基于KMeans的指数择时策略

    [导语]:聚类分析是指将物理或者抽象对象的结合分组为由类似对象组成的多个类的分析过程.简单来讲,聚类就是通过一些特征去自动识别一个大群体中的多个子群体,这些子群体中的对象彼此之间相似度高,而子群体之间 ...

  7. k8s framework

    reference 1. k8s master framework master master 是k8s cluster运行着daemon服务:kube-apiserver, kube-schedul ...

  8. SpringMVC+Spring+Mybatis整合程序之整合

    因为每个人思路不一样,所以我在这边先分享自己的思路对于mybatis开发持久层(DAO:DataBase Access Object 持久层访问对象)有两种.第一种:传统的开发持久层方式即需要程序员开 ...

  9. CS193p Lecture 10 - Multithreating, UIScrollView

    Multithreating(多线程) 网络请求例子: NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithStrin ...

  10. MySql的基操勿六

    2018/12/6 星期四 19:34:07 authot by dabaine 数据库注释; -- 这就是注释 /*.....*/ 这也是注释 创建库; create databse [if not ...