zoukankan      html  css  js  c++  java
  • 无题3

    第一题:

    插板法,多思考一下应该出得来;

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const ll mod = 998244353;
    const int M = 1000005;
    ll dp[M], fac[M], a[M], vfac[M], sum[M];
    ll ksm(ll a, ll b){
        ll ret=1;
        for(;b;b>>=1,a=a*a%mod)
        if(b&1) ret=ret*a%mod;
        return ret;
    }
    
    inline ll ni(ll a){
        return ksm(a, mod - 2);
    }
    
    int main(){
        freopen("qiang.in","r",stdin);
        freopen("qiang.out","w",stdout);
        int n;
        scanf("%d", &n); 
        fac[0] = vfac[0] = 1;
        
        dp[1] = 1;
        int x;
        for(int i = 1; i <= n; i++){
            scanf("%d", &a[i]);
            sum[i] = sum[i - 1] + a[i];
        }
        for(int i = 1; i <= sum[n]; i++) fac[i] = fac[i - 1] * 1LL*i % mod, vfac[i] = ni(fac[i]);
        for(int i = 2; i <= n; i++){
            dp[i] = dp[i - 1] * fac[sum[i] - 1] % mod * vfac[a[i] - 1] % mod * vfac[sum[i - 1]] % mod;
        }
        printf("%lld
    ",dp[n]);
    }
    View Code

    第二题:矩阵块速幂,又听zyy大佬讲了一遍,讲的太好了;

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int M = (1<<4) + 2;
    int n; ll mod;
    inline ll moc(int a){return a >= mod ? a - mod : a;}
    struct Maxtri{
        ll w[M][M];
        void unit(){
            for(int i = 0; i < M; i++)
                for(int j = 0; j < M; j++)
                    w[i][j] = (i == j);
        }
        void init(){
            for(int i = 0; i < M; i++)
                for(int j = 0; j < M; j++)
                    w[i][j] = 0;
        }
        void print(){
            for(int i = 0; i < M; i++){
                for(int j = 0; j < M; j++)printf("%d ", w[i][j]);puts("");
            }
                
        }
        
    }tr;
    
    Maxtri  operator *(const  Maxtri &s, const  Maxtri &t){
        Maxtri a;
        for(int i = 0; i < M; i++)
            for(int j = 0; j < M; j++){
                a.w[i][j] = 0;
                for(int k = 0; k < M; k++)
                    a.w[i][j] = moc(a.w[i][j] + s.w[i][k] * t.w[k][j] % mod);
            }
        return a;
                
    }
    
    Maxtri ksm(Maxtri a, int b){
        Maxtri ret;
        for(ret.unit(); b; b >>= 1, a=a*a)
            if(b & 1) ret = ret * a;
        return ret;
    }
    
    void dfs(int dep, int os, int ns){
        if(!dep) {
            tr.w[ns][os] = 1;
            return ;
        }
        if((1<<(dep-1))&os){
            dfs(dep - 1, os, ns);
            if(dep - 1 > 0 && ((1<<(dep-2))&os)) dfs(dep - 2, os, ns + (1<<(dep-1)) + (1<<(dep-2)));
        }
        else dfs(dep - 1, os, ns + (1<<(dep-1)));
    }
    
    
    int main(){
        freopen("count.in","r",stdin);
        freopen("count.out","w",stdout);
        int n;
        for(int i = 0; i < (1<<4); i++)
        dfs(4, i, 0);
        while(scanf("%d%lld", &n, &mod) == 2 && n && mod){
            Maxtri rec;
            rec.init();
            rec.w[(1<<4)-1][0] = 1;
            Maxtri ans = ksm(tr, n);
            //ans.print();
            ll res = ans.w[(1<<4)-1][(1<<4)-1];        
            printf("%lld
    ", res);    
        }
        
    }
    View Code

    第三题:先AB差分得到操作次数的数字,维护一个单调不降的数组,那么操作次数一定是第一个数;

    怎么维护单降序列:如果后面凸起来,  1.重开一个新的, 2.接在原来的线上,我们就需要额外操作;

    额外操作:(a[i] - a[i - 1] + 4) % 4, 使得当前操作次数不小于上一次操作次数;(相当于把新的填平了);

    不论合不合法都记录额外操作,当不合法时,选取之前最小的代价,使每一步最优;

    eg: 差分后数组

    #include<bits/stdc++.h>
    using namespace std;
    const int M = 100005;
    int a[M], b[M], s[15];
    
    int main(){
        freopen("sequence.in","r",stdin);
        freopen("sequence.out","w",stdout);
        int T;
        scanf("%d", &T);
        while(T--){
            memset(s, 0, sizeof(s));
            int n;
            scanf("%d", &n);
            for(int i = 1; i <= n; i++)scanf("%d", &a[i]);
            for(int i = 1; i <= n; i++)scanf("%d", &b[i]), a[i] = (b[i] - a[i] + 4) % 4;
            int ans = a[1];
            for(int i = 2; i <= n; i++){
                s[(a[i] - a[i - 1] + 4) % 4]++;
                if(a[i - 1] >= a[i])continue;
                int j;
                for(j=1;!s[j];j++);
                s[j]--;
                ans += j;
            }
            printf("%d
    ",ans);    
        }
        
    } 
    View Code
  • 相关阅读:
    vue --- 全局弹窗,只调用对应实例
    代理相关;win操作
    mongoBD + node + express
    菜鸟初学 node 推荐 亲测easy
    H5 ---- 点击遍历所有标签,复制对应的文本
    async与await初步应用
    C# Enum 添加自定义Attribute,然后通过泛型与反射的方式得到事先定义的标记
    VS2013 C# 调用 cognex 的QuickBuild做程序时发生一个错误
    C# 获取数组的内存地址
    利用反射插入数据库与更新数据库
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/9670547.html
Copyright © 2011-2022 走看看