题目大意

  给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数。

思路

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5.  
  6. const int MAX_INDEX = 100010, MAX_MAXVAL = MAX_INDEX, MAX_DEL_CNT = 50010, MAX_NODE = 9e6;
  7. int Queries[MAX_DEL_CNT];
  8. long long Ans[MAX_DEL_CNT];
  9. int TotIndex, TotDelCnt, MaxVal;
  10.  
  11. struct Data
  12. {
  13. int Index, Val, AddTime;
  14.  
  15. bool operator < (const Data& a) const
  16. {
  17. return AddTime < a.AddTime;
  18. }
  19. }_datas[MAX_INDEX];
  20.  
  21. struct Node
  22. {
  23. int lSonId, rSonId;
  24. int Cnt;
  25.  
  26. Node() :lSonId(0), rSonId(0), Cnt(0) {}
  27. }_nodes[MAX_NODE];
  28. int _vCount;
  29.  
  30. struct RangeTree
  31. {
  32. private:
  33. int RootId;
  34.  
  35. Node *NewNode()
  36. {
  37. return _nodes + ++_vCount;
  38. }
  39.  
  40. void Update(int &curId, int l, int r, int p, int delta)
  41. {
  42. Node *cur = _nodes + curId;
  43. if (!curId)
  44. {
  45. cur = NewNode();
  46. curId = cur - _nodes;
  47. }
  48. cur->Cnt += delta;
  49. if (l == r)
  50. return;
  51. int mid = (l + r) / 2;
  52. if (p <= mid)
  53. Update(cur->lSonId, l, mid, p, delta);
  54. if (p > mid)
  55. Update(cur->rSonId, mid + 1, r, p, delta);
  56. }
  57.  
  58. long long QueryPrefix(int k)
  59. {
  60. Node *cur = RootId ? _nodes + RootId : NULL;
  61. int l = 1, r = MaxVal;
  62. long long ans = 0;
  63. while (l < r && cur)
  64. {
  65. int mid = (l + r) / 2;
  66. if (k >= mid)
  67. {
  68. ans += cur->lSonId ?_nodes[cur->lSonId].Cnt :0;
  69. cur = cur->rSonId ? _nodes + cur->rSonId : NULL;
  70. l = mid + 1;
  71. }
  72. else
  73. {
  74. cur = cur->lSonId ? _nodes + cur->lSonId:NULL;
  75. r = mid;
  76. }
  77. }
  78. return ans;
  79. }
  80.  
  81. long long QuerySuffix(int k)
  82. {
  83. Node *cur = RootId ? _nodes + RootId : NULL;
  84. if (!cur)
  85. return 0;
  86. return cur->Cnt - QueryPrefix(k-1);
  87. }
  88.  
  89. public:
  90. RangeTree() :RootId(0) {}
  91.  
  92. void Update(int p, int delta)
  93. {
  94. if (p < 1 || p > MaxVal)
  95. return;
  96. Update(RootId, 1, MaxVal, p, delta);
  97. }
  98.  
  99. long long Query(int l, int r)
  100. {
  101. if (l > r)
  102. return 0;
  103. long long ans1 = 0;
  104. if (l == 1)
  105. {
  106. ans1 = QueryPrefix(r);
  107. return ans1;
  108. }
  109. else if (r == MaxVal)
  110. {
  111. ans1= QuerySuffix(l);
  112. return ans1;
  113.  
  114. }
  115. else
  116. return 0;
  117. }
  118. };
  119.  
  120. struct BinaryTree
  121. {
  122. private:
  123. RangeTree C[MAX_MAXVAL];
  124. int N;
  125.  
  126. int Lowbit(int x)
  127. {
  128. return x & -x;
  129. }
  130.  
  131. public:
  132. BinaryTree(int n) :N(n) {}
  133.  
  134. void Update(int p, int delta)
  135. {
  136. if (p < 0)
  137. return;
  138. while (p <= N)
  139. {
  140. C[p].Update(delta, 1);
  141. p += Lowbit(p);
  142. }
  143. }
  144.  
  145. long long Query(int p, long long(*getVal)(RangeTree&, int), int cKey)
  146. {
  147. long long ans = 0;
  148. while (p > 0)
  149. {
  150. ans += getVal(C[p], cKey);
  151. p -= Lowbit(p);
  152. }
  153. return ans;
  154. }
  155. }*a;
  156.  
  157. long long Range_GetIdGreaterCnt(RangeTree& tree, int k)
  158. {
  159. return tree.Query(k + 1, MaxVal);
  160. }
  161.  
  162. long long Range_GetIdLesserCnt(RangeTree& tree, int k)
  163. {
  164. return tree.Query(1, k - 1);
  165. }
  166.  
  167. void Update(Data& data)
  168. {
  169. a->Update(data.Val, data.Index);
  170. }
  171.  
  172. long long Query(Data& data)
  173. {
  174. return a->Query(data.Val - 1, Range_GetIdGreaterCnt, data.Index) +
  175. a->Query(MaxVal, Range_GetIdLesserCnt, data.Index) - a->Query(data.Val, Range_GetIdLesserCnt, data.Index);
  176. }
  177.  
  178. int main()
  179. {
  180. scanf("%d%d", &TotIndex, &TotDelCnt);
  181. MaxVal = TotIndex;
  182. static int Match[MAX_INDEX];
  183. for (int i = 1; i <= TotIndex; i++)
  184. {
  185. _datas[i].Index = i;
  186. scanf("%d", &_datas[i].Val);
  187. Match[_datas[i].Val] = i;
  188. }
  189. int addTime = TotDelCnt;
  190. for (int i = 1; i <= TotDelCnt; i++)
  191. {
  192. int delId;
  193. scanf("%d", &delId);
  194. _datas[Match[delId]].AddTime = addTime--;
  195. }
  196.  
  197. sort(_datas + 1, _datas + TotIndex + 1);
  198. a = new BinaryTree(MaxVal);
  199. long long tempAns = 0;
  200. for (int i = 1; i <= TotIndex - TotDelCnt; i++)
  201. {
  202. Update(_datas[i]);
  203. tempAns += Query(_datas[i]);
  204. }
  205. for (int i = TotIndex - TotDelCnt + 1; i <= TotIndex; i++)
  206. {
  207. Update(_datas[i]);
  208. Ans[_datas[i].AddTime] = tempAns += Query(_datas[i]);
  209. }
  210.  
  211. for (int i = TotDelCnt; i >= 1; i--)
  212. printf("%lld\n", Ans[i]);
  213. return 0;
  214. }

  

luogu3157 动态逆序对的更多相关文章

  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. 【Luogu1393】动态逆序对(CDQ分治)

    [Luogu1393]动态逆序对(CDQ分治) 题面 题目描述 对于给定的一段正整数序列,我们定义它的逆序对的个数为序列中ai>aj且i < j的有序对(i,j)的个数.你需要计算出一个序 ...

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

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

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

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

  6. cdq分治(hdu 5618 Jam's problem again[陌上花开]、CQOI 2011 动态逆序对、hdu 4742 Pinball Game、hdu 4456 Crowd、[HEOI2016/TJOI2016]序列、[NOI2007]货币兑换 )

    hdu 5618 Jam's problem again #include <bits/stdc++.h> #define MAXN 100010 using namespace std; ...

  7. P3157 [CQOI2011]动态逆序对(树状数组套线段树)

    P3157 [CQOI2011]动态逆序对 树状数组套线段树 静态逆序对咋做?树状数组(别管归并QWQ) 然鹅动态的咋做? 我们考虑每次删除一个元素. 减去的就是与这个元素有关的逆序对数,介个可以预处 ...

  8. P3157 [CQOI2011]动态逆序对

    P3157 [CQOI2011]动态逆序对 https://www.luogu.org/problemnew/show/P3157 题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai&g ...

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

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

随机推荐

  1. DOS批处理命令-字符串操作

    1.字符串替换 语法结构:%变量名:替换前=替换后% @set str=teh cat in teh hat @echo %str% @set str=%str:teh=the% @echo %str ...

  2. (转)Hibernate的配置详解

    http://blog.csdn.net/yerenyuan_pku/article/details/65041077 在<Hibernate快速入门>一文中,我有讲到Hibernate的 ...

  3. Java中的方法重写

    方法的重载: 在同一个类中,出现多个同名的方法,参数列表不同,与返回值类型,修饰符无关 方法的重写: 子类中出现和父类中一模一样的方法(包括返回值类型,方法名,参数列表) 方法重写的注意事项: 1.重 ...

  4. C3P0数据库连接池使用方法

    一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大 ...

  5. Linux 下phpstudy的安装使用补充说明

    (1)使用方法 在终端中使用sudo 或者 使用管理员账号运行 phpstudy start 开启 (2)命令列表: phpstudy start | stop | restart        开启 ...

  6. java静态变量、实例变量和局部变

    实例变量又称成员变量: 1⃣️成员变量定义在类中,在整个类中都可以被访问 2⃣️成员变量随着对象的建立而建立,随对象的消失而消失,存在于对象所在的对内存中 3⃣️成员变量有默认初始值 局部变量: 1⃣ ...

  7. 使用form标签时注意事项

    今天写程序的时候,使用了一个form:select标签,然后系统一直报错 原因找了好久也没找到 后来咨询得知, 在使用form:标签的时候  前后的form标签要写成<form:form> ...

  8. MarkDown 语法及使用

    MarkDown #什么是Markdown - 定义 - markdown 是一款轻量级标记语言,功能没有HTML标记语言那么强大 ,Markdown专注书写! #试用人群: 程序员/等计算机爱好者 ...

  9. 获取springbean的几种方式

    首先我说一下我遇到的问题,再项目初始化时候,spring容器初始化前要执行的操作中使用到了bean去做一些增删改查操作,这样做是不能自己使用springbean的数据源去操作的,所以需要动态获取spr ...

  10. 亚马逊免费服务器搭建Discuz!论坛过程(四)

    上述命令还可能因缺少包引发其他错误: 如果出错则安装对应的包即可. 以下供参考: yum install libxml2 yum install libxml2-devel -y yum instal ...