• [CQOI2018]交错序列


    [CQOI2018]交错序列

    [题目链接]

    链接

    [思路要点]

    比较简单的 (dp)

    状态比较好想,(f[i][j]) 表示当前填了前 (i) 个数字,第 (i) 个数字填了 (0) 的所有方案的 (1) 的个数的 (j) 次方和,(g[i][j]) 表示当前填了前 (i) 个数字,第 (i) 个数字填了 (1) 的所有方案的 (1) 的个数的 (j) 次方和

    转移:

    [f[i][j]=f[i -1][j]+g[i-1][j] \ g[i][j]=sum_{k=0}^{j} C_{j}^{k}cdot f[i-1][k] ]

    初值就是 (f[1][0]=1,f[1][其它]=0,g[1][所有]=1)

    然后放到矩阵里做矩乘

    [代码]

    // Copyright: lzt
    #include<stdio.h>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<cmath>
    #include<iostream>
    #include<queue>
    #include<string>
    #include<ctime>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef long double ld;
    typedef unsigned long long ull;
    typedef pair<long long,long long> pll;
    #define fi first
    #define se second
    #define pb push_back
    #define mp make_pair
    #define rep(i,j,k)  for(register int i=(int)(j);i<=(int)(k);i++)
    #define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--)
    #define Debug(...) fprintf(stderr, __VA_ARGS__)
    
    ll read(){
        ll x=0,f=1;char c=getchar();
        while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0' && c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    const int maxn = 110;
    int n, a, b, mod;
    int C[maxn][maxn];
    int f[110], g[110];
    
    inline int sum(int x, int y) {
        return x + y >= mod ? x + y - mod : x + y;
    }
    inline int sub(int x, int y) {
        return x - y < 0 ? x - y + mod : x - y;
    }
    
    inline int ksm(int x, int p) {
        int ret = 1;
        while (p) {
            if (p & 1) ret = ret * 1ll * x % mod;
            p >>= 1; x = x * 1ll * x % mod;
        }
        return ret;
    }
    
    int N;
    struct Matrix {
        int a[185][185];
        Matrix (int x = 0) {
            memset(a, 0, sizeof(a));
            if (x == 1) rep(i, 0, 184) a[i][i] = 1;
        }
        inline Matrix operator * (const Matrix &b) const {
            Matrix ret;
            rep(i, 0, N) rep(j, 0, N) if (a[i][j] != 0) {
                rep(k, 0, N) ret.a[i][k] = sum(ret.a[i][k], a[i][j] * 1ll * b.a[j][k] % mod);
            }
    //		rep(i, 0, N) rep(j, 0, N) rep(k, 0, N) ret.a[i][j] = sum(ret.a[i][j], a[i][k] * 1ll * b.a[k][j] % mod);
            return ret;
        }
    };
    
    inline Matrix ksm(Matrix &x, int p) {
        Matrix ret(1);
        while (p) {
            if (p & 1) ret = ret * x;
            x = x * x; p >>= 1;
        }
        return ret;
    }
    
    void work() {
        n = read(), a = read(), b = read(), mod = read();
        C[0][0] = 1;
        rep(i, 1, a + b) {
            C[i][0] = 1;
            rep(j, 1, i) C[i][j] = sum(C[i - 1][j], C[i - 1][j - 1]);
        }
        Matrix A;
        A.a[0][0] = 1;
        rep(i, 1, a + b) A.a[0][i] = 0;
        rep(i, a + b + 1, a + b + a + b + 1) A.a[0][i] = 1;
        N = a + b + a + b + 1;
        Matrix B;
        rep(j, 0, a + b) B.a[j][j] = 1, B.a[j + a + b + 1][j] = 1;
        rep(j, 0, a + b) {
            int nwj = a + b + 1 + j;
            rep(k, 0, j) B.a[k][nwj] = C[j][k];
        }
        A = A * ksm(B, n - 1);
        rep(i, 0, a + b) f[i] = A.a[0][i];
        rep(i, 0, a + b) g[i] = A.a[0][a + b + 1 + i];
        int ans = 0;
        rep(i, 0, a) {
            if ((a - i) & 1) ans = sub(ans, ksm(n, i) * 1ll * C[a][i] % mod * sum(f[a + b - i], g[a + b - i]) % mod);
            else ans = sum(ans, ksm(n, i) * 1ll * C[a][i] % mod * sum(f[a + b - i], g[a + b - i]) % mod);
        }
        printf("%d
    ", ans);
    }
    
    int main(){
        #ifdef LZT
            freopen("in","r",stdin);
        #endif
    
        work();
    
        #ifdef LZT
            Debug("My Time: %.3lfms
    ", (double)clock() / CLOCKS_PER_SEC);
        #endif
    }
    
  • 相关阅读:
    【codevs1949】兔兔与蛋蛋的游戏
    【codevs1775】那些年
    【codevs3153】取石子
    [codevs1909]英语 博弈论
    spfa及slf优化
    [baoj3224]普通平衡树
    恋爱路上的几个叉
    考研之如何联系导师
    《C++程序设计语言(特别版)》忠告(advice)部分
    一位程序猿送给女朋友的礼物
  • 原文地址:https://www.cnblogs.com/wawawa8/p/11113776.html
Copyright © 2020-2023  润新知