Problem Statement

You are given an integer sequence of length $N$: $A_1,A_2,...,A_N$. Let us perform $Q$ operations in order.
The $i$-th operation is described by two integers $X_i$ and $Y_i$. In this operation, we will choose one of the following two actions and perform it:

  • Swap the values of $A_{X_i}$ and $A_{Y_i}$
  • Do nothing

There are $2^Q$ ways to perform these operations. Find the sum of the inversion numbers of the final sequences for all of these ways to perform operations, modulo $10^9+7$.

Here, the inversion number of a sequence $P_1,P_2,...,P_M$ is the number of pairs of integers $(i,j)$ such that $1\leq i < j\leq M$ and $P_i > P_j$.

Constraints

  • $1 \leq N \leq 3000$
  • $0 \leq Q \leq 3000$
  • $0 \leq A_i \leq 10^9(1\leq i\leq N)$
  • $1 \leq X_i,Y_i \leq N(1\leq i\leq Q)$
  • $X_i\neq Y_i(1\leq i\leq Q)$
  • All values in input are integers.

先定义 \(dp_{i,j}\) 为 \(a_i<a_j\) 的方案数。

然后发现一次交换会改变所有的 \(dp_{i,j}\)。但是大多的 \(dp_{i,j}\) 都是乘上2,除了 \(x_i\) 和 \(y_i\) 相关的 dp 以外。

所以把 \(dp_{i,j}\) 的定义改为 \(a_i>a_j\) 的概率,然后每次只有 \(O(n)\) 个 dp 值会修改。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=3005,P=1e9+7,iv2=P+1>>1;
  4. int n,q,pw[N],dp[N][N],a[N],x,y,ans,g1[N],g2[N];
  5. int main()
  6. {
  7. scanf("%d%d",&n,&q);
  8. for(int i=1;i<=n;i++)
  9. scanf("%d",a+i);
  10. for(int i=1;i<=n;i++)
  11. for(int j=1;j<=n;j++)
  12. dp[i][j]=a[i]>a[j];
  13. for(int i=pw[0]=1;i<=q;i++)
  14. {
  15. pw[i]=pw[i-1]<<1;
  16. if(pw[i]>=P)
  17. pw[i]-=P;
  18. }
  19. for(int i=1;i<=q;i++)
  20. {
  21. scanf("%d%d",&x,&y);
  22. for(int i=1;i<=n;i++)
  23. g1[i]=dp[i][x]&1? dp[i][x]+P>>1:dp[i][x]>>1,g2[i]=dp[x][i]&1? dp[x][i]+P>>1:dp[x][i]>>1;
  24. for(int i=1;i<=n;i++)
  25. {
  26. if(i^x&&i^y)
  27. {
  28. dp[i][x]=(dp[i][x]&1? dp[i][x]+P>>1:dp[i][x]>>1)+(dp[i][y]&1? dp[i][y]+P>>1:dp[i][y]>>1);
  29. if(dp[i][x]>=P)
  30. dp[i][x]-=P;
  31. }
  32. }
  33. for(int i=1;i<=n;i++)
  34. {
  35. if(i^x&&i^y)
  36. {
  37. dp[x][i]=(dp[x][i]&1? dp[x][i]+P>>1:dp[x][i]>>1)+(dp[y][i]&1? dp[y][i]+P>>1:dp[y][i]>>1);
  38. if(dp[x][i]>=P)
  39. dp[x][i]-=P;
  40. }
  41. }
  42. for(int i=1;i<=n;i++)
  43. {
  44. if(i^y&&i^x)
  45. {
  46. dp[i][y]=(dp[i][y]&1? dp[i][y]+P>>1:dp[i][y]>>1)+g1[i];
  47. if(dp[i][y]>=P)
  48. dp[i][y]-=P;
  49. }
  50. }
  51. for(int i=1;i<=n;i++)
  52. {
  53. if(i^y&&i^x)
  54. {
  55. dp[y][i]=(dp[y][i]&1? dp[y][i]+P>>1:dp[y][i]>>1)+g2[i];
  56. if(dp[y][i]>=P)
  57. dp[y][i]-=P;
  58. }
  59. }
  60. dp[x][y]=dp[y][x]=(dp[x][y]+dp[y][x])*1LL*iv2%P;
  61. }
  62. for(int j=1;j<n;j++)
  63. {
  64. for(int k=j+1;k<=n;k++)
  65. {
  66. ans+=dp[j][k];
  67. if(ans>=P)
  68. ans-=P;
  69. }
  70. }
  71. printf("%lld",ans*1LL*pw[q]%P);
  72. }

[AGC030D] Inversion Sum的更多相关文章

  1. CF258D Little Elephant and Broken Sorting/AGC030D Inversion Sum 期望、DP

    传送门--Codeforces 传送门--Atcoder 考虑逆序对的产生条件,是存在两个数\(i,j\)满足\(i < j,a_i > a_j\) 故设\(dp_{i,j}\)表示\(a ...

  2. 「AGC030D」Inversion Sum

    「AGC030D」Inversion Sum 传送门 妙啊. 由于逆序对的个数最多只有 \(O(n^2)\) 对,而对于每一个询问与其相关的逆序对数也最多只有 \(O(n)\) 对,我们可以对于每一对 ...

  3. 【AGC030D】Inversion Sum DP

    题目大意 有一个序列 \(a_1,a_2,\ldots,a_n\),有 \(q\) 次操作,每次操作给你两个数 \(x,y\),你可以交换 \(a_x,a_y\),或者什么都不做. 问你所有 \(2^ ...

  4. AGC 030D.Inversion Sum(DP 期望)

    题目链接 \(Description\) 给定长为\(n\)的序列\(A_i\)和\(q\)次操作\((x,y)\).对于每次操作\((x,y)\),可以选择交换\(A_x,A_y\)两个数,也可以选 ...

  5. CSP-S2020 DP专项训练

    前言 \(\text{CPS-S2020}\) 已然临近,而 \(\text{DP}\) 作为联赛中的常考内容,是必不可少的复习要点,现根据教练和个人刷题,整理部分好题如下(其实基本上是直接搬--). ...

  6. AtCoder Grand Contest 030题解

    第一次套刷AtCoder 体验良好 传送门 Poisonous Cookies cout<<b+min(c,a+b+); Tree Burning 难度跨度有点大啊 可以证明当第一次转向之 ...

  7. AGC030 简要题解

    A - Poisonous Cookies 题意 有\(A\)个能解毒的普通饼干,\(B\)个能解毒的美味饼干,\(C\)个有毒的美味饼干,求最多能吃多少个美味饼干,每次吃完有毒的饼干后要解毒后才能继 ...

  8. 【AtCoder】AGC030

    A - Poisonous Cookies 有毒还吃,有毒吧 #include <bits/stdc++.h> #define fi first #define se second #de ...

  9. AtCoder Grand Contest 030 Solution

    A - Poisonous Cookies 签到. #include <bits/stdc++.h> using namespace std; #define ll long long l ...

  10. AtCoder练习

    1. 3721 Smuggling Marbles 大意: 给定$n+1$节点树, $0$为根节点, 初始在一些节点放一个石子, 然后按顺序进行如下操作. 若$0$节点有石子, 则移入盒子 所有石子移 ...

随机推荐

  1. 大规模 IoT 边缘容器集群管理的几种架构-6-个人体验及推荐

    前文回顾 大规模 IoT 边缘容器集群管理的几种架构-0-边缘容器及架构简介 大规模 IoT 边缘容器集群管理的几种架构-1-Rancher+K3s 大规模 IoT 边缘容器集群管理的几种架构-2-H ...

  2. ctypes使用浅谈

    什么是ctypes: ctypes 是 Python 的一个标准库,用于与 C 语言进行交互.它提供了一组工具和函数,可以方便地调用动态链接库(DLL)或共享对象(SO)中的 C 函数,并处理 C 数 ...

  3. 我们能从PEP 703中学到什么

    PEP703是未来去除GIL的计划,当然现在提案还在继续修改,但大致方向确定了. 对于实现细节我没啥兴趣多说,挑几个我比较在意的点讲讲. 尽量少依赖原子操作的引用计数 没了GIL之后会出现两个以上的线 ...

  4. 为何 Linus 一个人就能写出这么强的系统,中国却做不出来?

    前言 知乎上有一个提问:为何 Linus 一个人就能写出这么强的系统,中国却做不出来? ↓↓↓ 今天,我们就这个话题,一起来做个讨论. 不知道大家是怎么看这个问题的?是美国人更聪明吗,所以才能写出这么 ...

  5. 如何对MongoDB进行测试

    一.环境搭建 关于环境搭建,最好的搭建方式,当然是脚本一键式搭建 我这里是centos6 x64版本的linux上进行构建,这个linux版本现在应该是大部分的主流服务器的标配版本 下面是安装脚本的编 ...

  6. 一款国产开源 Web 防火墙神器!

    随着开源 Web 框架和各种建站工具的兴起,搭建网站已经是一件成本非常低的事情,但是网站的安全性很少有人关注,以至于 WAF 这个品类也鲜为人知. 一.WAF 是什么? WAF 是 Web 应用防火墙 ...

  7. Python/Java/Php/C#/Go/C/C++这几个主力语言,谁到底真的不行

    1.前言 阿里最近又进行了史诗级的大裁员,IT行业肉眼可见的持续性衰退与没落.当潮水退却,才能看出谁在裸泳.作为当今计算机编程界的几大主力语言,谁才真正的裸泳者呢? 2.描述 1.Python: Py ...

  8. LUA的一些工具备份

    table.unpack遇到的问题 做了个中转的服务, socket+json 传递数据, 通过 {...} 封装不定参数然后 json.encode 传递到其他服务器, 然后其他服务器 json.d ...

  9. SYN泛洪攻击详解

    SYN攻击利用的是TCP的三次握手机制,攻击端利用伪造的IP地址向被攻击端发出请求,而被攻击端发出的响应 报文将永远发送不到目的地,那么被攻击端在等待关闭这个连接的过程中消耗了资源,如果有成千上万的这 ...

  10. WebKit Insie: Active 样式表

    WebKit Inside: CSS 样式表的匹配时机介绍了当 HTML 页面有不同 CSS 样式表引入时,CSS 样式表开始匹配的时机.后续文章继续介绍 CSS 样式表的匹配过程,但是在匹配之前,首 ...