AGC 030D.Inversion Sum(DP 期望)
\(Description\)
给定长为\(n\)的序列\(A_i\)和\(q\)次操作\((x,y)\)。对于每次操作\((x,y)\),可以选择交换\(A_x,A_y\)两个数,也可以选择不进行操作。求所有\(2^q\)种情况中,逆序对个数之和。
\(n,q\leq3000\)。
\(Solution\)
不去直接求和,我们求\(q\)次操作后逆序对的期望个数。这样乘上\(2^q\)就是答案。
可以令\(f[t][i][j]\)表示,\(t\)次操作后,\(A_i<A_j\)的概率。
\(f[0][i][j]\)可以由初始序列得到,然后可以从\(f[t-1][i][j]\)转移到\(f[t][i][j]\),但这样好像是\(O(n^2q)\)的?
对于每次操作\((x,y)\),只会影响\(i\)或\(j\)等于\(x\)或\(y\)时的\(f[t][i][j]\),其它的都不会变。所以只需要修改这\(O(n)\)个值就可以了。(比如\(f[i][x]\)即\(a_i<a_x\)的概率,现在\(\frac12\)会变成\(a_i<a_y\)的概率,即\(f[i][x]=\frac{f[i][x]+f[i][y]}{2}\),\(f[i][y]\)同理)
复杂度\(O(n^2+qn)\)。
话说Um_nik是什么写法啊。。。
//310ms 35456KB
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define mod 1000000007
#define inv2 500000004ll
typedef long long LL;
const int N=3005;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
}
inline int FP(int x,int k)
{
int t=1;
for(; k; k>>=1,x=1ll*x*x%mod)
if(k&1) t=1ll*t*x%mod;
return t;
}
int main()
{
static int A[N],f[N][N];
const int n=read(),q=read();
for(int i=1; i<=n; ++i) A[i]=read();
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j) f[i][j]=A[i]<A[j];
for(int i=1; i<=q; ++i)
{
int x=read(),y=read();
f[x][y]=f[y][x]=inv2*(f[x][y]+f[y][x])%mod;
for(int j=1; j<=n; ++j)
if(j!=x && j!=y)
f[j][x]=f[j][y]=inv2*(f[j][x]+f[j][y])%mod,
f[x][j]=f[y][j]=inv2*(f[x][j]+f[y][j])%mod;
}
LL ans=0;
for(int i=1; i<=n; ++i)
for(int j=1; j<i; ++j) ans+=f[i][j];
printf("%lld\n",ans%mod*FP(2,q)%mod);
return 0;
}
AGC 030D.Inversion Sum(DP 期望)的更多相关文章
- 【AGC030D】Inversion Sum DP
题目大意 有一个序列 \(a_1,a_2,\ldots,a_n\),有 \(q\) 次操作,每次操作给你两个数 \(x,y\),你可以交换 \(a_x,a_y\),或者什么都不做. 问你所有 \(2^ ...
- CF258D Little Elephant and Broken Sorting/AGC030D Inversion Sum 期望、DP
传送门--Codeforces 传送门--Atcoder 考虑逆序对的产生条件,是存在两个数\(i,j\)满足\(i < j,a_i > a_j\) 故设\(dp_{i,j}\)表示\(a ...
- 概率dp+期望dp 题目列表(一)
表示对概率和期望还不是很清楚定义. 目前暂时只知道概率正推,期望逆推,然后概率*某个数值=期望. 为什么期望是逆推的,例如你求到某一个点的概率我们可以求得,然后我们只要运用dp从1~n每次都加下去就好 ...
- 「AGC030D」Inversion Sum
「AGC030D」Inversion Sum 传送门 妙啊. 由于逆序对的个数最多只有 \(O(n^2)\) 对,而对于每一个询问与其相关的逆序对数也最多只有 \(O(n)\) 对,我们可以对于每一对 ...
- [CF697D]Puzzles 树形dp/期望dp
Problem Puzzles 题目大意 给一棵树,dfs时随机等概率选择走子树,求期望时间戳. Solution 一个非常简单的树形dp?期望dp.推导出来转移式就非常简单了. 在经过分析以后,我们 ...
- Max Sum(dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003 Max Sum Time Limit: 2000/1000 MS (Java/Others) ...
- HDOJ(HDU).1003 Max Sum (DP)
HDOJ(HDU).1003 Max Sum (DP) 点我挑战题目 算法学习-–动态规划初探 题意分析 给出一段数字序列,求出最大连续子段和.典型的动态规划问题. 用数组a表示存储的数字序列,sum ...
- Problem Arrangement ZOJ - 3777(状压dp + 期望)
ZOJ - 3777 就是一个入门状压dp期望 dp[i][j] 当前状态为i,分数为j时的情况数然后看代码 有注释 #include <iostream> #include <cs ...
- 2017 ICPC Asia Urumqi A.coins (概率DP + 期望)
题目链接:Coins Description Alice and Bob are playing a simple game. They line up a row of nn identical c ...
随机推荐
- CF939F
好神奇的dp... 首先有一个很简单的思想:设dp[i][j]表示目前到了第i分钟,朝上的面被烤了j分钟的情况下所需的最小交换次数 那么有转移:dp[i][j]=min(dp[i-1][j],dp[i ...
- Android Studio 创建不恰当的虚拟设备导致程序不正常运行
操作系统:Windows 10 x64 IDE:Android Studio 3.2.1 使用Android Studio新建第一个Android程序,一开始在虚拟设备上面调试,不管程序怎么修改,运行 ...
- axure—日期函数
日期函数 日期函数中实现倒计时的关键点:1)gettime()函数可以取到1970年1月1日的时间,我们用倒计时结束的时间减去当前时间就能得到倒计时需要循环显示的所有时间.2)此处的“d”是倒计时结束 ...
- JMeter 提供了六种定时器
JMeter提供了六种定时器,下面让我们一起来学习下JMeter的定时器. 先明确一些概念: 1)定时器是在每个sampler(采样器)之前执行的,而不是之后: 是的,你没有看错,不管这个定时器的位置 ...
- SQLServer 常见高CPU利用率原因
1.缺失索引: USE AdventureWorks2014 SET STATISTICS TIME ON; SET STATISTICS IO ON ; SELECT per.FirstName,p ...
- 剑指offer错题记录
错误重点: 1. 传递vector参数时,如果调用函数改变了vector的内容,一定一定要&,传引用保持一致 旋转数组的最小数字:有重复数字情况,二分查找照样搞.情况考虑要周全,当a[mid] ...
- 搭建自己的docker仓库
https://docs.docker.com/registry/deploying/#run-a-local-registry https://docs.docker.com/registry/in ...
- eclipse 编辑代码区字体大小
wiondow-->preferences-->general-->appearance-->colors and fonts-->java-->java edit ...
- python全栈开发day58-mysql存储过程,权限,索引,慢日志,执行计划,分页优化处理
1.存储过程 delimiter // create procedure insert_data(in rows int) begin DECLARE n INT DEFAULT 1; drop ta ...
- WPF: Hide grid row
http://stackoverflow.com/questions/2502178/wpf-hide-grid-row Setting all the Items in the Row to Vis ...