• 2019牛客暑期多校训练营(第五场)


    2019牛客暑期多校训练营(第五场)

    题号 标题 已通过代码 题解/讨论 通过率 团队的状态
    A digits 2 点击查看 进入讨论 1016/2378 通过
    B generator 1 点击查看 进入讨论 513/3524 通过
    C generator 2 点击查看 进入讨论 34/592 已补
    D generator 3 点击查看 进入讨论 4/23 未通过
    E independent set 1 点击查看 进入讨论 36/98 队友已补
    F maximum clique 1 点击查看 进入讨论 77/779 队友已补
    G subsequence 1 点击查看 进入讨论 494/2432 通过
    H subsequence 2 点击查看 进入讨论 278/1311 通过
    I three points 1 点击查看 进入讨论 125/2614 未通过
    J three points 2 点击查看 进入讨论 4/70 队友已补

    lwqtql:https://www.cnblogs.com/lwqq3/

    zgtql:http://brotherzhi.com/

    A

    #include <bits/stdc++.h>
    using namespace std;
    int T;
    int n;
    int main(){
     
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            for(int i=1;i<=n;i++)printf("%d",n);
            puts("");
        }
        return 0;
    }
    

    B

    矩阵快速幂

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll mod;
     
    struct node {
        ll c[2][2];
    };
     
    node mul(node x, node y) {
        node res;
        memset(res.c, 0, sizeof(res.c));
     
        for(int i = 0; i < 2; i++)
        for(int j = 0; j < 2; j++)
        for(int k = 0; k < 2; k++)
            res.c[i][j] = (res.c[i][j] + x.c[i][k] * y.c[k][j] % mod) % mod;
        return res;
    }
     
    node pow_mod(node x, ll y) {
        node res;
        res.c[0][0] = res.c[1][1] = 1LL;
        res.c[0][1] = res.c[1][0] = 0LL;
     
        while(y) {
            if(y & 1) res = mul(res, x);
            x = mul(x, x);
            y >>= 1;
        }
        return res;
    }
     
    char s[1000005];
    int ss[1000005];
    int main() {
        ll x0, x1, a, b;
        cin>>x0>>x1>>a>>b;
        scanf("%s", s + 1);
        int len = strlen(s + 1);
        for(int i = 1; i <= len; i++) ss[i] = s[i] - '0';
        cin>>mod;
     
        node A;
        A.c[0][0] = a;
        A.c[0][1] = b;
        A.c[1][0] = 1LL;
        A.c[1][1] = 0LL;
        if(len == 1) {
            if(s[1] == '1') {
                printf("%lld
    ", x1);
                return 0;
            }
        }
        ss[len]--;
        for(int i = len; i >= 1; i--) {
            if(ss[i] < 0) {
                ss[i] += 10;
                ss[i - 1]--;
            }
        }
     
     
        node now;
        now.c[0][0] = now.c[1][1] = 1LL; now.c[0][1] = now.c[1][0] = 0LL;
        for(int i = 1; i <= len; i++) {
            now = pow_mod(now, 10);
            int t = ss[i];
     
            node pp = pow_mod(A, 1LL * t);
            now = mul(now, pp);
        }
        ll ans = now.c[0][0] * x1 % mod + now.c[0][1] * x0 % mod;
        ans %= mod;
        printf("%lld
    ", ans);
        return 0;
    }
    

    C

    写了篇题解https://www.cnblogs.com/1625--H/p/11291238.html

    BSGS

    E

    位元状压DP

    #include <bits/stdc++.h>
    using namespace std;
     
    char dp[1 << 26];
    int adj[30];
     
    int main() {
        int n, m;
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= m; i++) {
            int u, v;
            scanf("%d%d", &u, &v);
            adj[u] |= (1 << v);
            adj[v] |= (1 << u);
        }
        for(int i = 0; i < n; i++) adj[i] = (~adj[i]), adj[i] ^= (1 << i);
        //puts("??");
        for(int i = 1; i < (1 << n); i++) {
            int t = __builtin_ctz(i);
            dp[i] = max(dp[i - (1 << t)], (char)(dp[i & adj[t]] + 1));
        }
        int ans = 0;
        for(int i = 1; i < (1 << n); i++) ans += dp[i];
        printf("%d
    ", ans);
        return 0;
    }
    

    G

    思路跟标程反了。一直没调对,不知道那里出错了。

    下面是按照标程思路写的。思路也不是很难,如果按照长度等不等区分开来进行DP的话,就要额外维护一个东西。

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 3030;
    const int mod = 998244353;
    typedef long long ll;
    char s[N],t[N];
    int n,m;
    ll d[N][N],C[N][N];
    void predo(){
        C[0][0] = 1;
        for(int i=1;i<N;i++){
            C[i][0] = 1;
            for(int j=1;j<N;j++)
                C[i][j] = (C[i-1][j] + C[i-1][j-1])%mod;
        }
    }
    void add(ll &x,ll y){x = (x + y)%mod;}
    void DP(){
        for(int i=0;i<=n;i++)d[i][0] = 1;
        for(int i=0;i<=n;i++)if(s[i] == t[1])d[i][1] = 1;
        for(int j=2;j<=m;j++){
            ll sum = 0;
            for(int i=1;i<=n;i++){
                if(s[i] == t[j])
                    add(d[i][j],sum);
                add(sum,d[i][j-1]);
            }
        }
    }
    int main(){
        int tt;scanf("%d",&tt);
        predo();
        while(tt--){
            scanf("%d%d",&n,&m);
            scanf("%s%s",s+1,t+1);
            ll res = 0;
            for(int i=0;i<=n+1;i++)for(int j=0;j<=n+1;j++)d[i][j] = 0;
            DP();
            for(int i=1;i<=n;i++)
                if(s[i]!='0')
                    for(int j=m;j<=(n-i);j++)
                        add(res,C[n-i][j]);
            for(int j=m;j>=1;j--){
                ll sum = j == 1;
                for(int i=1;i<=n;i++){
                    if(s[i] > t[j])
                        add(res,sum * C[n-i][m-j]);
                    if(j>1)add(sum,d[i][j-1]);
                }
            }
            cout<<res<<endl;
        }
        return 0;
    }
    

    H

    对于每两个字母,都能知道单个字符前面有多少个别类字符,所有的情况加起来后就知道前面总共有多少个字符了。不可能的情况可能出现在

    • 两次输入中,同一类型字母个数不同
    • 总个数不够n个
    • 两个字符位置相同
    • 有地方空着,或者填入了超出n的位置
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 10010;
    int num[20][10010];
    int tot[20];
    int n,m;
    char s[N];
    char ans[10*N];
    int main(){
        scanf("%d%d",&n,&m);
        bool flag = true;
        for(int i=1;i<=m*(m-1)/2;i++){
            char a,b;
            int len;
            cin>>a>>b;scanf("%d",&len);
            if(len == 0){
                getchar();continue;
            }
            scanf("%s",s);
            int cnta = 0,cntb = 0;
            for(int i=0;i<len;i++){
                if(s[i] == a)cnta++,num[a-'a'][cnta] += cntb;
                if(s[i] == b)cntb++,num[b-'a'][cntb] += cnta;
            }
            //判断个数与之前是否一致
            if(tot[a-'a'] == 0){
                tot[a-'a'] = cnta;
            }
            else if(tot[a-'a'] != cnta){
                flag = false;
            }
            if(tot[b-'a'] == 0){
                tot[b-'a'] = cntb;
            }
            else if(tot[b-'a'] != cntb){
                flag  = false;
            }
        }
        for(int i=0;i<m;i++){
            for(int j=1;j<=tot[i];j++){
                //判断是否有重位,或者位置范围超出n
                if(ans[num[i][j] + j-1] != 0 || num[i][j] + j-1 >= n){
                    flag = false;break;
                } 
                ans[num[i][j] + j-1] = 'a'+i;
            }  
            if(!flag)break;
        }
        int sum = 0;for(int i=0;i<m;i++)sum += tot[i];
        if(sum != n)flag = false;
        ans[sum] = '';
        if(flag)printf("%s
    ",ans);
        else printf("-1");
        return 0;
    }
    
  • 相关阅读:
    Centos7下安装7za 及7za常用命令
    n2n搭建手记-2-V2
    n2n搭建手记-1-V1
    centos 7 下发送邮件设置
    Centos7 下安装mysql
    C#设计模式之11:命令模式
    asp.net core实时库:SignalR(1)
    asp.net core 排序过滤分页组件:sieve(2)表达式树的复习
    asp.net core 排序过滤分页组件:sieve
    linux上面sqlserver数据库的操作
  • 原文地址:https://www.cnblogs.com/1625--H/p/11285495.html
Copyright © 2020-2023  润新知