[AGC030D] Inversion Sum
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的更多相关文章
- CF258D Little Elephant and Broken Sorting/AGC030D Inversion Sum 期望、DP
传送门--Codeforces 传送门--Atcoder 考虑逆序对的产生条件,是存在两个数\(i,j\)满足\(i < j,a_i > a_j\) 故设\(dp_{i,j}\)表示\(a ...
- 「AGC030D」Inversion Sum
「AGC030D」Inversion Sum 传送门 妙啊. 由于逆序对的个数最多只有 \(O(n^2)\) 对,而对于每一个询问与其相关的逆序对数也最多只有 \(O(n)\) 对,我们可以对于每一对 ...
- 【AGC030D】Inversion Sum DP
题目大意 有一个序列 \(a_1,a_2,\ldots,a_n\),有 \(q\) 次操作,每次操作给你两个数 \(x,y\),你可以交换 \(a_x,a_y\),或者什么都不做. 问你所有 \(2^ ...
- AGC 030D.Inversion Sum(DP 期望)
题目链接 \(Description\) 给定长为\(n\)的序列\(A_i\)和\(q\)次操作\((x,y)\).对于每次操作\((x,y)\),可以选择交换\(A_x,A_y\)两个数,也可以选 ...
- CSP-S2020 DP专项训练
前言 \(\text{CPS-S2020}\) 已然临近,而 \(\text{DP}\) 作为联赛中的常考内容,是必不可少的复习要点,现根据教练和个人刷题,整理部分好题如下(其实基本上是直接搬--). ...
- AtCoder Grand Contest 030题解
第一次套刷AtCoder 体验良好 传送门 Poisonous Cookies cout<<b+min(c,a+b+); Tree Burning 难度跨度有点大啊 可以证明当第一次转向之 ...
- AGC030 简要题解
A - Poisonous Cookies 题意 有\(A\)个能解毒的普通饼干,\(B\)个能解毒的美味饼干,\(C\)个有毒的美味饼干,求最多能吃多少个美味饼干,每次吃完有毒的饼干后要解毒后才能继 ...
- 【AtCoder】AGC030
A - Poisonous Cookies 有毒还吃,有毒吧 #include <bits/stdc++.h> #define fi first #define se second #de ...
- AtCoder Grand Contest 030 Solution
A - Poisonous Cookies 签到. #include <bits/stdc++.h> using namespace std; #define ll long long l ...
- AtCoder练习
1. 3721 Smuggling Marbles 大意: 给定$n+1$节点树, $0$为根节点, 初始在一些节点放一个石子, 然后按顺序进行如下操作. 若$0$节点有石子, 则移入盒子 所有石子移 ...
随机推荐
- 解放生产力orm并发更新下应该这么处理求求你别再用UpdateById了
解放生产力orm并发更新下应该这么处理求求你别再用UpdateById了 背景 很多时候为了方便我们都采用实体对象进行前后端的数据交互,然后为了便捷开发我们都会采用DTO对象进行转换为数据库对象,然后 ...
- 如何修改min.js或者压缩后的js,以便提高代码的可读性。
前端的js上线的时候一般会使用打包工具处理(webpack,gulp,ugly.js 等).这样做有几点作用. 可以压缩空间,提高页面响应速度 一定程度上可以保护自己的代码安全,防止别人清晰看懂逻辑或 ...
- 问题总结:浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用equals来判断
浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用equals来判断. 说明:浮点数采用"尾数+阶码"的编码方式,类似于科学计数法的"有效数字+指数& ...
- .NET C#基础(9):资源释放 - 需要介入的资源管理
1. 什么是IDisposable? IDisposable接口是一个用于约定可进行释放资源操作的接口,一个类实现该接口则意味着可以使用接口约定的方法Dispose来释放资源.其定义如下: pub ...
- Python脚本批量造数据、跑定时任务协助测试
批量造数据 连接Mysql的信息 1 import pymysql 2 # 数据库连接信息 3 # 多个库要有多个conn 4 conn = pymysql.connect( 5 host=" ...
- ES6-ES11最通俗易懂保姆级的笔记!人见人爱,花见花开。赶快动起你发财的小手收藏起来吧,满满的干货,你值得拥有!!
1. ES6 1.1 let变量声明以及声明特性 声明变量 let a; let b, c, e; let f = 100, g = "红石榴21", h = []; 特性: ...
- 基于go语言gin框架的web项目骨架
该骨架每个组件之间可单独使用,组件之间松耦合,高内聚,组件的实现基于其他三方依赖包的封装. 目前该骨架实现了大多数的组件,比如事件,中间件,日志,配置,参数验证,命令行,定时任务等功能,目前可以满足大 ...
- C++的动态分派在HotSpot VM中的重要应用
众所周知,多态是面向对象编程语言的重要特性,它允许基类的指针或引用指向派生类的对象,而在具体访问时实现方法的动态绑定.C++ 和 Java 作为当前最为流行的两种面向对象编程语言,其内部对于多态的支持 ...
- Host-Only模式下虚拟机无法联网问题
环境: 镜像:Linux CentOS7 \-----------------------------------------\ 问题描述: 虚拟设置了Host-Only模式的虚拟网卡VMNet4,并 ...
- 其它-Supervisor的使用
文章目录 Supervisor 的使用 一 Supervisor介绍 二 安装 2.1 安装方式 2.2 验证 2.3 配置 2.4 配置详情(了解) 2.5 启动.停止.重启 三 program 配 ...