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 值会修改。

#include<bits/stdc++.h>
using namespace std;
const int N=3005,P=1e9+7,iv2=P+1>>1;
int n,q,pw[N],dp[N][N],a[N],x,y,ans,g1[N],g2[N];
int main()
{
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)
scanf("%d",a+i);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dp[i][j]=a[i]>a[j];
for(int i=pw[0]=1;i<=q;i++)
{
pw[i]=pw[i-1]<<1;
if(pw[i]>=P)
pw[i]-=P;
}
for(int i=1;i<=q;i++)
{
scanf("%d%d",&x,&y);
for(int i=1;i<=n;i++)
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;
for(int i=1;i<=n;i++)
{
if(i^x&&i^y)
{
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);
if(dp[i][x]>=P)
dp[i][x]-=P;
}
}
for(int i=1;i<=n;i++)
{
if(i^x&&i^y)
{
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);
if(dp[x][i]>=P)
dp[x][i]-=P;
}
}
for(int i=1;i<=n;i++)
{
if(i^y&&i^x)
{
dp[i][y]=(dp[i][y]&1? dp[i][y]+P>>1:dp[i][y]>>1)+g1[i];
if(dp[i][y]>=P)
dp[i][y]-=P;
}
}
for(int i=1;i<=n;i++)
{
if(i^y&&i^x)
{
dp[y][i]=(dp[y][i]&1? dp[y][i]+P>>1:dp[y][i]>>1)+g2[i];
if(dp[y][i]>=P)
dp[y][i]-=P;
}
}
dp[x][y]=dp[y][x]=(dp[x][y]+dp[y][x])*1LL*iv2%P;
}
for(int j=1;j<n;j++)
{
for(int k=j+1;k<=n;k++)
{
ans+=dp[j][k];
if(ans>=P)
ans-=P;
}
}
printf("%lld",ans*1LL*pw[q]%P);
}

[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. 质量管理 | QC、QA、QM,去QA化与降本增效

    现在国内职业的质量管理都是从 CMMI 和 ISO 质量体系演化过来的,但是能做真正的质量管理的公司很少.质量管理的 QC 偏测试,对最终的产品负责:QA 偏过程,从过程把控质量:QM 偏体系,类似于 ...

  2. 《Linux基础》07. 软件管理

    @ 目录 1:软件管理 1.1:rpm 1.1.1:查询 1.1.2:卸载 1.1.3:安装 1.2:yum 1.3:dpkg 1.4:apt 1.4.1:相关配置 1.4.2:常用指令 1.4.3: ...

  3. MindSponge分子动力学模拟——使用迭代器进行系统演化(2023.09)

    技术背景 在前面几篇博客中,我们已经介绍过使用MindSponge去定义一个系统以及使用MindSponge计算一个分子系统的单点能.这篇文章我们将介绍一下在MindSponge中定义迭代器Updat ...

  4. 每日一库:Prometheus

    什么是 Prometheus Prometheus 是一个开源的系统监控和警报工具,最初由 SoundCloud 开发,并于 2012 年发布为开源项目.它是一个非常强大和灵活的工具,用于监控应用程序 ...

  5. ES6-ES11最通俗易懂保姆级的笔记!人见人爱,花见花开。赶快动起你发财的小手收藏起来吧,满满的干货,你值得拥有!!

    1.  ES6 1.1  let变量声明以及声明特性 声明变量 let a; let b, c, e; let f = 100, g = "红石榴21", h = []; 特性: ...

  6. 关于tiptop gp5.2采购模块,价格变更的随笔

    采购价格变更要看具体环节,你可以把他当作是三张表,采购价格表.收货价格表.入库价格表,这些还好处理,如果已抛砖到财务端生成账款再要求改价格就更复杂,会产生更多张表了,改起来也就更复杂. 用apmt91 ...

  7. Thinking in Java 4th Edition Source Code

    Thinking in Java 4th Edition Source Code Instructions for downloading, installing and testing the so ...

  8. 【RocketMQ】RocketMQ存储结构设计

    CommitLog 生产者向Broker发送的消息,会以顺序写的方式,写入CommitLog文件,CommitLog文件的根目录由配置参数storePathRootDir决定,默认每一个CommitL ...

  9. Keycloak 创建和修改自定义用户信息

    前言 公司在用 Keycloak 作为认证服务器,之前在系统数据库里存的,后来想了想是不是可以在 Keycloak 中存.在网上找的方法大多都是通过 admin 接口去改,但这种方法就需要两种解决方案 ...

  10. MSFvenom恶意程序生成与利用

    MSFvenom 1.1 MSFvenom介绍 MSFvenom是Msfpayload和Msfencode的组合,可以生成各种攻击载荷,并且可以对载荷进行编码.做渗透测试时往往需要将有效负载部署在目标 ...