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
  • 相关阅读:
    121. Best Time to Buy and Sell Stock
    70. Climbing Stairs
    647. Palindromic Substrings
    609. Find Duplicate File in System
    583. Delete Operation for Two Strings
    556 Next Greater Element III
    553. Optimal Division
    539. Minimum Time Difference
    537. Complex Number Multiplication
    227. Basic Calculator II
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/9670547.html
Copyright © 2011-2022 走看看