CF1151FSonya and Informatics

给一个长度为 n$ (n\leq 100)$的 \(0/1\) 串,进行 k\((k \leq 10^9)\)次操作,每次操作选择两个位置 \((i,j)\)\((i < j)\),交换$ i,j$ 上的数,求 \(k\) 次操作后,该 \(0/1\) 串变成非降序列的概率,答案对 \(10^9+7\) 取模。

首先这道题目我们可以想出来一下比较朴素的DP

我们设\(sum_0\)为原列中\(0\)个数

我们发现我们不关心序列长什么样子

只关心前\(sum_0\)个数中\(0\)个个数

设\(f_{i,j}\)表示前\(i\)次操作之后,还有\(j\)个\(0\)的方案数

概率可以转化为

\[\frac{f_{k,sum_0}}{\sum_{i = 0}^{sum_0} f_{k,i}}
\]

转移就是

设\(c = \frac{n*(n - 1)}{2}\)表示总的可能情况

\[f_{i,j} += f_{i - 1,j - 1}+(sum_0 - (j - 1)) * (sum_0 - (j - 1))
\]

把一个前面的\(1\)换成\(0\)前部分有\(sum_0- (j - 1)\)个\(1\),后一部分有\(sum_0 - (j - 1)\)个\(0\),两两配对的方案数

\[f_{i,j} += f_{i - 1,j + 1} + (j + 1) * (sum_1 - (sum_0 - (j + 1)))
\]

把一个前面的\(0\)换成\(1\),组合意义类似上面

\[f_{i,j} += f_{i - 1,j} + (c - v_1 - v_2)
\]

\(v_1,v_2\)就是上面两个式子的后面部分

表示没有对前面的\(0\)的数目产生影响

这之后我们观察一下这个转移每次转移只和\(j\)有关

我们考虑使用矩阵去优化这个东西

\[\left[\begin{array}{ccccc}{f_{0}[0]} & {f_{-1}[1]} & {0} & {\dots} & {0} \\ {f_{+1}[0]} & {f_{0}[1]} & {f_{-1}[2]} & {\dots} & {0} \\ {0} & {f_{+1}[1]} & {f_{0}[2]} & {\dots} & {0} \\ {\dots} & {\dots} & {\dots} & {\dots} & {\dots}\\{0}&{0}&{0}&{\dots} &{f_0[n]}\end{array}\right]
\left[\begin{array}{c}{d p[0]} \\ {d p[1]} \\ {d p[2]} \\ {\cdots} \\ {d p[n]}\end{array}\right]=\left[\begin{array}{c}{d p[0]} \\ {d p[1]} \\ {d p[2]} \\ {\cdots} \\ {d p[n]}\end{array}\right]
\]

大约是这个样子

我们这样就完成了一次转移

\(k\)很大

我们直接上矩阵快速幂就可以了

\(\mathcal{O}\left(n^{3} \log k\right)\)

#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
using namespace std;
const int N = 105;
const LL mod = 1e9 + 7;
int n,k;
int a[N];
LL sum0,sum1;
inline int read(){
int v = 0,c = 1;char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') c = -1;
ch = getchar();
}
while(isdigit(ch)){
v = v * 10 + ch - 48;
ch = getchar();
}
return v * c;
}
inline LL up(LL x){
if(x >= mod) x -= mod;
return x;
}
inline LL down(LL x){
if(x < 0) x += mod;
return x;
}
struct Ma{
LL a[N][N];
LL *operator[](int i){return a[i];}
inline void clear(){memset(a,0,sizeof(a));}
friend Ma operator * (Ma x,Ma y){
Ma c;c.clear();
for(int i = 0;i <= n;++i)
for(int j = 0;j <= n;++j)
for(int k = 0;k <= n;++k)
c.a[i][j] = (c.a[i][j] + (x.a[i][k] * y.a[k][j])) % mod;
return c;
}
};
Ma s,ss;
inline Ma quick(Ma x,int y){
Ma res;
for(int i = 0;i <= n;++i) res[i][i] = 1;
while(y){
if(y & 1) res = res * x;
y >>= 1;
x = x * x;
}
return res;
}
Ma dp;
LL inv;
inline LL p3(LL x){
return x * (sum0 - (sum1 - x)) % mod;
}
inline LL p2(LL x){
LL v1 = sum1 * (sum1 - 1) / 2;
LL v2 = sum0 * (sum0 - 1) / 2;
LL v3 = x * (sum1 - x) % mod;
LL v4 = (sum1 - x) * (sum0 - (sum1 - x)) % mod;
return (v1 + v2 + v3 + v4) % mod;
}
inline LL p1(LL x){
return (sum1 - x) * (sum1 - x) % mod;
}
inline LL quickmul(LL x,LL y){
LL res = 1;
while(y){
if(y & 1) res = res * x % mod;
x = x * x % mod;
y >>= 1;
}
return res;
}
int main(){
n = read(),k = read();
for(int i = 1;i <= n;++i){
a[i] = read() ^ 1;
sum0 += (a[i] == 0);
sum1 += (a[i] == 1);
}
LL t = 0;
for(int i = 1;i <= sum1;++i) t += (a[i] == 1);
dp[t][0] = 1;
for(int i = 0;i <= sum1;++i){
if(i > 0) ss.a[i][i - 1] = p1(i - 1);
ss.a[i][i] = p2(i);
if(i + 1 <= sum1) ss.a[i][i + 1] = p3(i + 1);
}
Ma ans = quick(ss,k) * dp;
Ma aa = quick(ss,k);
LL res = 0;
for(int i = 0;i <= sum1;++i) res = (res + ans[i][0]) % mod;
printf("%lld\n",ans[sum1][0] * quickmul(res,mod - 2) % mod);
return 0;
}

CF1151FSonya and Informatics的更多相关文章

  1. Python for Informatics 第11章 正则表达式六(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 11.7 调试 Python有一 ...

  2. Python for Informatics 第11章 正则表达式五(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 11.4 转义字符 之前我们在正 ...

  3. Python for Informatics 第11章 正则表达式四(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 11.3 组合查询和抽取 如果我 ...

  4. Python for Informatics 第11章 正则表达式三(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 11.2 用正则表达式抽取数据 ...

  5. Python for Informatics 第11章 正则表达式二(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 11.1 正则表达式的字符匹配 ...

  6. Python for Informatics 第11章 正则表达式一(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 目前为止,我们一直在通读文件,查 ...

  7. 【CF1151F】Sonya and Informatics(动态规划,矩阵快速幂)

    [CF1151F]Sonya and Informatics(动态规划,矩阵快速幂) 题面 CF 题解 考虑一个暴力\(dp\).假设有\(m\)个\(0\),\(n-m\)个\(1\).设\(f[i ...

  8. Protocol Informatics (PI项目)【基于网络轨迹的协议逆向工程文献学习】

    Protocol Informatics[基于网络轨迹的协议逆向工程文献学习]by tsy 声明: 1)本报告由博客园bitpeach撰写,版权所有,免费转载,请注明出处,并请勿作商业用途.恕作者著作 ...

  9. Nastya Studies Informatics CodeForces - 992B (大整数)

    B. Nastya Studies Informatics time limit per test 1 second memory limit per test 256 megabytes input ...

随机推荐

  1. oracle触发器——ddl触发器

    什么是ddl(data definition language),说白了就是我们经常用的create.alter和drop这些数据定义语句. n  创建ddl触发器 请编写一个触发器,可以记录某个用户 ...

  2. MySQL主备模式的数据一致性解决方案

     根据阿里交易型业务的特点,以及在双十一这样业内罕有的需求推动下,我们在官方的MySQL基础上增加了非常多实用的功能.性能补丁.而在使用MySQL的过程中,数据一致性是绕不开的话题之一.本文主要从阿里 ...

  3. 程序中提醒用户进去App Store 评分 跳转 代码

           大家都知道,评论和评分是决定app在appstore中排名的重要因素,但是大部分用户下载安装APP后却不会去点评,所以添加提示用户去点评的功能是很必要的,如下是代码: 很多用户用了好软件 ...

  4. hdu2018 dp

    /* 1~4直接取得: 然后后面的生牛的时候都是前一年的加上一定的数. 从第5年看,第五年出生的牛肯定要加上第四年出生的,然后由于第一个出生的牛开始生小牛,这和 最开始的牛生孩子是一样的,所以+dp[ ...

  5. iOS 适配iPhoneX上tableHeaderView发生了高度拉伸、UI出现的空白间距

    记录下前阵子遇到的一个问题,草稿箱里记录的有点潦草,讲下大概吧. 异常如下,粉色区域作为tableHeader放上去的(注意不是sectionHeader) header初始化之后一切正常,frame ...

  6. 实用的cmd命令

    1.打开iis服务器:inetmgr 2.远程连接:mstsc 3.注册表:regedit.exe

  7. Gym-101623H_High Score

    题意:t组数据,每组数据有abcd四个数,其中d可以加到abc任意一个数上(d可以拆分),求公式a^2 + b^2 + c^2 + 7 * min(a,b,c)的最大值. 题解:首先明确一点,平方的增 ...

  8. LeetCode Weekly Contest 6

    leetcode现在每周末举办比赛,这是今天上午参加的比赛的题解.题目难度不算大,两个easy,一个medium,一个hard.hard题之前接触过,所以做得比较顺利. 1.  Sum of Left ...

  9. saltStack_Pillar

    Pillar是Salt非常重要的一个组件,它用于给特定的minion定义任何你需要的数据,这些数据可以被Salt的其他组件使用.这里可以看出Pillar的一个特点,Pillar数据是与特定minion ...

  10. 手机QQ浏览器属于代理服务器吗?

    这两天.上QQ,会员上线提示.老是显示福建省,而没有具体的地方.这是怎么回事呢?而且那个时间段我都没有上QQ.但是有用手机QQ浏览器.偷菜.这是怎么回事,机子也没有病毒 没有木马 到底怎么搞的...! ...