CF1151FSonya and Informatics

Posted wyxdrqc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1151FSonya and Informatics相关的知识,希望对你有一定的参考价值。

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\)的方案数

概率可以转化为
\[ \fracf_k,sum_0\sum_i = 0^sum_0 f_k,i \]
转移就是

\(c = \fracn*(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[\beginarraycccccf_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]\endarray\right] \left[\beginarraycd p[0] \\ d p[1] \\ d p[2] \\ \cdots \\ d p[n]\endarray\right]=\left[\beginarraycd p[0] \\ d p[1] \\ d p[2] \\ \cdots \\ d p[n]\endarray\right] \]
大约是这个样子

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

\(k\)很大

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

\(\mathcalO\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的主要内容,如果未能解决你的问题,请参考以下文章

CF1151F Sonya and Informatics (计数dp+矩阵优化)

CF1151div2(Round 553)

cf1151e number of components

[lightoj P1151] Snakes and Ladders

Snakes and Ladders LightOJ - 1151

[原创][Synth 8-2543] port connections cannot be mixed ordered and named ["*_Top.v":1151](代码片