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

Input

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

Output

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

Sample Input5 4 1 5 3 4 2 5 1 4 2

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

思路:逆序对删除可以看作是三维偏序问题,三元组<pos,val,time>,排序定一序,分治定一序,一维直接树状数组维护求和即可

满足逆序对有2种情况:

1.pos0>pos, val0<val, time0<time

2.pos0<pos, val0>val, time0<time

可以在读入时定pos的序,就是求每个点左边值大于这个点的和右边值小于这个点的关于时间的偏序,时间都要大于这个点

在分治时,保证两个区间的pos是有序的,但区间内不保证,因为他们是val序,所以左右区间一个查询一个修改,就能保证pos序了

这样,在分治时分别统计两次即可,注意每次都要清空影响,最后直接用sort排序即可,因为时间大于这个点,所以统计的数量是sum(m+1)-sum(time0)

  1. using namespace std;
  2. #define lowbit(x) ((x)&(-x))
  3. typedef long long LL;
  4.  
  5. const int maxm = 1e5+;
  6.  
  7. int C[maxm], n, m, ans[maxm], Cache[maxm];
  8.  
  9. void add(int x, int val) {
  10. for(; x <= n+; x += lowbit(x))
  11. C[x] += val;
  12. }
  13.  
  14. int getsum(int x) {
  15. int ret = ;
  16. for(; x; x -= lowbit(x))
  17. ret += C[x];
  18. return ret;
  19. }
  20.  
  21. struct Node {
  22. int val, tim, ans;
  23. } buf[maxm], res[maxm];
  24.  
  25. bool cmpval(Node a, Node b) {
  26. return a.val < b.val;
  27. }
  28.  
  29. void CDQ(int L, int R) {
  30. if(L == R) return;
  31. int mid = (L+R) >> ;
  32. CDQ(L, mid), CDQ(mid+, R);
  33. int i = L, j = mid+;
  34. // 计算右边小于他的
  35. while(i <= mid && j <= R) {
  36. if(res[i].val > res[j].val)
  37. add(res[j++].tim, );
  38. else
  39. res[i].ans += getsum(m+)-getsum(res[i++].tim);
  40. }
  41. while(i <= mid)
  42. res[i].ans += getsum(m+)-getsum(res[i++].tim);
  43. // 清除数组
  44. for(int l = mid+; l < j; ++l)
  45. add(res[l].tim, -);
  46.  
  47. i = mid, j = R;
  48. //左边大于他的
  49. while(j > mid && i >= L) {
  50. if(res[j].val < res[i].val)
  51. add(res[i--].tim, );
  52. else
  53. res[j].ans += getsum(m+)-getsum(res[j--].tim);
  54. }
  55. while(j > mid)
  56. res[j].ans += getsum(m+)-getsum(res[j--].tim);
  57. for(int r = mid; r > i; --r)
  58. add(res[r].tim, -);
  59. sort(res+L, res+R+, cmpval);
  60. }
  61.  
  62. bool cmp2(Node a, Node b) {
  63. return a.tim < b.tim;
  64. }
  65.  
  66. int main() {
  67. scanf("%d%d", &n, &m);
  68. int t;
  69. for(int i = ; i <= n; ++i) {
  70. scanf("%d", &t);
  71. res[i] = {t};
  72. Cache[t] = i;
  73. }
  74. for(int i = ; i <= m; ++i) {
  75. scanf("%d", &t);
  76. res[Cache[t]].tim = i;
  77. }
  78. for(int i = ; i <= n; ++i)
  79. if(res[i].tim == )
  80. res[i].tim = m + ;
  81. LL ans = ;
  82. for(int i = ; i <= n; ++i) {
  83. add(res[i].val, );
  84. ans += i - getsum(res[i].val);
  85. }
  86. for(int i = ; i <= n; ++i)
  87. add(res[i].val, -);
  88. CDQ(, n);
  89. sort(res+, res++n, cmp2);
  90. for(int i = ; i <= m; ++i) printf("%lld\n", ans), ans -= res[i].ans;
  91. return ;
  92. }

Day6 - M - 动态逆序对 HYSBZ - 3295的更多相关文章

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

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

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

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

  3. BZOJ 3295 动态逆序对 | CDQ分治

    BZOJ 3295 动态逆序对 这道题和三维偏序很类似.某个元素加入后产生的贡献 = time更小.pos更小.val更大的元素个数 + time更小.pos更大.val更小的元素个数. 分别用类似C ...

  4. [BZOJ 3295] [luogu 3157] [CQOI2011]动态逆序对(树状数组套权值线段树)

    [BZOJ 3295] [luogu 3157] [CQOI2011] 动态逆序对 (树状数组套权值线段树) 题面 给出一个长度为n的排列,每次操作删除一个数,求每次操作前排列逆序对的个数 分析 每次 ...

  5. bzoj3295[Cqoi2011]动态逆序对 树套树

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

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

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

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

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

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

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

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

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

随机推荐

  1. 4.ORM框架的查询

    创建表对应关系代码如下: from flask import Flask, render_template from flask_sqlalchemy import SQLAlchemy app=Fl ...

  2. LIBRA查询

    SELECT COUNT(1)FROM rawdata_vehiclepassing xWHERE x.passingtime >= to_date('2019-11-24,00:00:00', ...

  3. 了解 C++

    C++的历史 C++由C语言发展演变而来,最初被称为"带类的C" 1983年正式取名为C++ 1998年11月被国籍标准化组织(ISO)批准为国际标准 2003年10月15日发布了 ...

  4. 什么是 SDK?

    通俗而言: 1.其实很简单,SDK 就是 Software Development Kit 的缩写,中问意思是: 软件开发工具包. 2.这是一个覆盖面相当广泛的名词,可以这么说: 辅助开发某一类软件的 ...

  5. ZOJ4103 Traveler(2019浙江省赛)

    构造+思维~ #include<bits/stdc++.h> using namespace std; ; int N,M,T; int visit[maxn]; stack<int ...

  6. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 网格系统实例:列排序

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. shell脚本中执行shell脚本(2)

    (a.sh)读取用户输入参数,并在脚本(b.sh)中使用 1.a.sh #!/bin/sh read -p "please input name value: " name ./b ...

  8. frp 配置

    前言 对于没有公网 IP 的内网用户来说,远程管理或在外网访问内网机器上的服务是一个问题. 今天给大家介绍一款好用内网穿透工具 FRP,FRP 全名:Fast Reverse Proxy.FRP 是一 ...

  9. Atcoder Grand Contest 037B(DP,组合数学,思维)

    #include<bits/stdc++.h>using namespace std;const long long mod = 998244353;string s;int a[3000 ...

  10. 【PAT甲级】1017 Queueing at Bank (25 分)

    题意: 输入两个正整数N,K(N<=10000,k<=100)分别表示用户的数量以及银行柜台的数量,接下来N行输入一个字符串(格式为HH:MM:SS)和一个正整数,分别表示一位用户到达银行 ...