题目大意:

给定一个长为\(n\)的序列,\(m\)次询问,每次查询一个区间的逆序对数。

32MB。

解题思路:

出题人题解

众所周知lxl是个毒瘤,Ynoi道道都是神仙题

二次离线莫队。

对于每个区间\([l,r]\),考虑将右端点向右移动1格。

其多出来的部分是\([l,r]\)与\(a_{r+1}\)产生的逆序对(\(a\)与\(b\)产生的逆序对和\(b\)与\(a\)产生的逆序对是不同的)。

显然,可以把\([l,r]\)区间拆成\([1,r]-[1,l-1]\)。

所以,\([l,r]\)与\(a_{r+1}\)产生的逆序对=\([1,r]\)与\(a_{r+1}\)产生的逆序对-\([1,l-1]\)与\(a_{r+1}\)产生的逆序对。

右端点不断移动,区间\([1,r]\)始终在变,而\([1,l-1]\)却是不变的。

我们先考虑\([1,r]\)与\(a_{r+1}\)产生的逆序对,显然可以用树状数组在\(O(n\log n)\)的时间内预处理出这个东西的前缀和。

然后莫队端点移动、计算这部分贡献的时候就可以做到\(O(1)\)。

然后考虑\([1,l-1]\)与\(a_{r+1}\)产生的逆序对,假设\(r\)要移动到\(r'\)(\(r< r' \))。

那么,这部分产生的贡献其实是\([1,l-1]\)与\([r,r']\)产生的逆序对。

考虑用一个vector,\(v_i\)记录\([1,i]\)这个区间与其他哪些区间会产生逆序对。

由于莫队的复杂度证明,\(v_i\)记录的区间的长度总和不超过\(O(n\sqrt n)\),所以直接扫描线,然后暴力计算贡献即可。

其他端点移动方法也是类似处理一下即可。

现在,我们需要一种数据结构,支持\(O(1)\)查询前缀和,不超过\(O(\sqrt n)\)的时间进行单点修改。

那么用权值分块即可,记录块的前缀和和每个位置到该位置所在块的块首的前缀和即可。

由于我们计算的是每个询问与上一个询问的差,所以最后要进行一次前缀和。

时间复杂度\(O(n\sqrt n+n\log n)\),空间复杂度\(O(n+m)\)。

C++ Code:

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<vector>
  4. #include<cctype>
  5. #include<cstring>
  6. #define N 100005
  7. #define siz 317
  8. class istream{
  9. char buf[15000003],*s;
  10. public:
  11. inline istream(){
  12. buf[fread(s=buf,1,15000001,stdin)]='\n';
  13. fclose(stdin);
  14. }
  15. template<typename T>
  16. inline istream&operator>>(T&rhs){
  17. for(rhs=0;!isdigit(*s);++s);
  18. while(isdigit(*s))rhs=rhs*10+(*s++&15);
  19. return*this;
  20. }
  21. }cin;
  22. struct ostream{
  23. char buf[8000005],*s;
  24. inline ostream(){s=buf;}
  25. inline void operator<<(long long d){
  26. if(!d){
  27. *s++='0';
  28. }else{
  29. static long long w;
  30. for(w=1;w<=d;w*=10);
  31. for(;w/=10;d%=w)*s++=d/w^'0';
  32. }
  33. *s++='\n';
  34. }
  35. inline ostream&operator<<(const char&c){*s++=c;return*this;}
  36. inline~ostream(){fwrite(buf,1,s-buf,stdout);}
  37. }cout;
  38. std::vector<int>ls;
  39. int n,m,a[N];
  40. long long L_R[N],R_L[N],ans[N],out[N];
  41. struct BiT{
  42. int b[N];
  43. inline void add(int i){for(;i<N;i+=i&-i)++b[i];}
  44. inline int ask(int i){int x=0;for(;i;i^=i&-i)x+=b[i];return x;}
  45. }b;
  46. struct que{
  47. int l,r,id;
  48. inline bool operator<(const que&rhs)const{
  49. return(l/siz!=rhs.l/siz)?(l<rhs.l):(r<rhs.r);
  50. }
  51. }q[N];
  52. struct node{
  53. int l,r,id,op;
  54. };
  55. std::vector<node>L[N],R[N];
  56. int bL[320],bR[320],bel[123456],c[123456],s[320];
  57. int main(){
  58. ls.push_back(-1);
  59. cin>>n>>m;
  60. for(int i=1;i<=n;ls.push_back(a[i++]))cin>>a[i];
  61. std::sort(ls.begin(),ls.end());
  62. ls.erase(std::unique(ls.begin(),ls.end()),ls.end());
  63. for(int i=1;i<=n;++i)a[i]=std::lower_bound(ls.begin(),ls.end(),a[i])-ls.begin();
  64. for(int i=1;i<=n;++i){
  65. L_R[i]=L_R[i-1]+b.ask(1e5)-b.ask(a[i]);
  66. b.add(a[i]);
  67. }
  68. memset(b.b,0,sizeof b.b);
  69. for(int i=n;i;--i){
  70. R_L[i]=R_L[i+1]+b.ask(a[i]-1);
  71. b.add(a[i]);
  72. }
  73. for(int i=1;i<=m;++i)cin>>q[i].l>>q[q[i].id=i].r;
  74. std::sort(q+1,q+m+1);
  75. q[0].l=1;
  76. for(int i=1;i<=m;++i){
  77. ans[i]=L_R[q[i].r]-L_R[q[i-1].r]+R_L[q[i].l]-R_L[q[i-1].l];
  78. if(q[i].r>q[i-1].r)
  79. R[q[i-1].l-1].push_back((node){q[i-1].r+1,q[i].r,i,-1});
  80. else
  81. if(q[i].r<q[i-1].r)
  82. R[q[i-1].l-1].push_back((node){q[i].r+1,q[i-1].r,i,1});
  83. if(q[i].l<q[i-1].l)
  84. L[q[i].r+1].push_back((node){q[i].l,q[i-1].l-1,i,-1});
  85. else
  86. if(q[i].l>q[i-1].l)
  87. L[q[i].r+1].push_back((node){q[i-1].l,q[i].l-1,i,1});
  88. }
  89. for(int i=1;i<=siz;++i){
  90. bL[i]=bR[i-1]+1;
  91. bR[i]=i*siz;
  92. for(int j=bL[i];j<=bR[i];++j)bel[j]=i;
  93. }
  94. for(int i=1;i<=n;++i){
  95. for(int j=1;j<bel[a[i]];++j)++s[j];
  96. for(int j=bL[bel[a[i]]];j<=a[i];++j)++c[j];
  97. for(node j:R[i]){
  98. int l=j.l,r=j.r;
  99. long long tmp=0;
  100. for(int k=l;k<=r;++k)
  101. tmp+=s[bel[a[k]+1]]+c[a[k]+1];
  102. ans[j.id]+=j.op*tmp;
  103. }
  104. }
  105. memset(c,0,sizeof c);
  106. memset(s,0,sizeof s);
  107. for(int i=n;i;--i){
  108. for(int j=bel[a[i]]+1;j<=siz;++j)++s[j];
  109. for(int j=a[i];j<=bR[bel[a[i]]];++j)++c[j];
  110. for(node j:L[i]){
  111. int l=j.l,r=j.r;
  112. long long tmp=0;
  113. for(int k=l;k<=r;++k)
  114. tmp+=s[bel[a[k]-1]]+c[a[k]-1];
  115. ans[j.id]+=j.op*tmp;
  116. }
  117. }
  118. for(int i=1;i<=m;++i)ans[i]+=ans[i-1],out[q[i].id]=ans[i];
  119. for(int i=1;i<=m;++i)cout<<out[i];
  120. return 0;
  121. }

  

[Ynoi2019模拟赛]Yuno loves sqrt technology II的更多相关文章

  1. [Ynoi2019模拟赛]Yuno loves sqrt technology II(二次离线莫队)

    二次离线莫队. 终于懂了 \(lxl\) 大爷发明的二次离线莫队,\(\%\%\%lxl\) 二次离线莫队,顾名思义就是将莫队离线两次.那怎么离线两次呢? 每当我们将 \([l,r]\) 移动右端点到 ...

  2. [Luogu5048] [Ynoi2019模拟赛]Yuno loves sqrt technology III[分块]

    题意 长为 \(n\) 的序列,询问区间众数,强制在线. \(n\leq 5\times 10^5\). 分析 考虑分块,暴力统计出整块到整块之间的众数次数. 然后答案还可能出现在两边的两个独立的块中 ...

  3. [luogu5048] [Ynoi2019模拟赛] Yuno loves sqrt technology III

    题目链接 洛谷. Solution 思路同[BZOJ2724] [Violet 6]蒲公英,只不过由于lxl过于毒瘤,我们有一些更巧妙的操作. 首先还是预处理\(f[l][r]\)表示\(l\sim ...

  4. [洛谷P5048][Ynoi2019模拟赛]Yuno loves sqrt technology III

    题目大意:有$n(n\leqslant5\times10^5)$个数,$m(m\leqslant5\times10^5)$个询问,每个询问问区间$[l,r]$中众数的出现次数 题解:分块,设块大小为$ ...

  5. 洛谷P5048 [Ynoi2019模拟赛]Yuno loves sqrt technology III(分块)

    传送门 众所周知lxl是个毒瘤,Ynoi道道都是神仙题 用蒲公英那个分块的方法做结果两天没卡过去→_→ 首先我们分块,预处理块与块之间的答案,然后每次询问的时候拆成整块和两边剩下的元素 整块的答案很简 ...

  6. Luogu P5048 [Ynoi2019模拟赛]Yuno loves sqrt technology III 分块

    这才是真正的$N\sqrt{N}$吧$qwq$ 记录每个数$vl$出现的位置$s[vl]$,和每个数$a[i]=vl$是第几个$vl$,记为$P[i]$,然后预处理出块$[i,j]$区间的答案$f[i ...

  7. P5048 [[Ynoi2019模拟赛]Yuno loves sqrt technology III]

    为什么我感觉这题难度虚高啊-- 区间众数的出现次数- 计算器算一下 \(\sqrt 500000 = 708\) 然后我们发现这题的突破口? 考虑分块出来[L,R]块的众数出现个数 用 \(\text ...

  8. 洛谷 P5048 - [Ynoi2019 模拟赛] Yuno loves sqrt technology III(分块)

    题面传送门 qwq 感觉跟很多年前做过的一道题思路差不多罢,结果我竟然没想起那道题?!!所以说我 wtcl/wq 首先将 \(a_i\) 离散化. 如果允许离线那显然一遍莫队就能解决,复杂度 \(n\ ...

  9. 洛谷 P5046 [Ynoi2019 模拟赛] Yuno loves sqrt technology I(分块+卡常)

    洛谷题面传送门 zszz,lxl 出的 DS 都是卡常题( 首先由于此题强制在线,因此考虑分块,我们那么待查询区间 \([l,r]\) 可以很自然地被分为三个部分: 左散块 中间的整块 右散块 那么这 ...

随机推荐

  1. 0816关于MySQL的审计 init-connect+binlog实现用户操作追踪

    转自:http://blog.sina.com.cn/s/blog_605f5b4f01013xkv.html mysql 用init-connect+binlog实现用户操作追踪 做access 的 ...

  2. 【ACM】hdu_1092_A+BIV_201307261630

    A+B for Input-Output Practice (IV)Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/3276 ...

  3. codevs——T3111 CYD啃骨头

     http://codevs.cn/problem/3111/  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Desc ...

  4. HDU 2255 奔小康赚大钱 KM算法题解

    KM算法求的是完备匹配下的最大权匹配,是Hungary算法的进一步,由于Hungary算法是最大匹配的算法,不带权. 经典算法,想不出来的了,要參考别人的.然后消化吸收吧. 由于真的非常复杂的算法. ...

  5. Windows XP时代终结:假设你还在用它怎么办

    2014 年 4 月 8 日.是Windows XP退休的日子. 4 月 8 日过后,Windows XP 的安全性更新将停止了. watermark/2/text/aHR0cDovL2Jsb2cuY ...

  6. cocos2d-x 是怎样渲染的

    要知道 是怎样渲染的:要先选中 就可以 谁知道: c ocos2d-x 是怎样渲染的 ? 每一个CCNODE自己有draw 北京-菜菜: :: draw draw负重渲染 ************** ...

  7. poj 2135 Farm Tour 【无向图最小费用最大流】

    题目:id=2135" target="_blank">poj 2135 Farm Tour 题意:给出一个无向图,问从 1 点到 n 点然后又回到一点总共的最短路 ...

  8. Google的TensorFlow,微软CNTK, Amazon 的MxNet,Facebook 的Caffe2, PyTorch,国内百度的PaddlePaddle

    深度学习框架竞争很激烈,而且看上去都是业界巨头在玩. 老师木:是的.一个深度学习框架一旦像Hadoop那样成为事实工业标准,就占据了人工智能各种关键应用的入口,对各类垂直应用,基于私有部署的技术服务, ...

  9. nyoj--523--亡命逃窜(BFS水题)

    亡命逃窜 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 从前有个叫hck的骑士,为了救我们美丽的公主,潜入魔王的老巢,够英雄吧.不过英雄不是这么好当的.这个可怜的娃被魔 ...

  10. 【HAOI 2008】 移动玩具

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1054 [算法] 广度优先搜索 [代码] #include<bits/stdc+ ...