zoukankan      html  css  js  c++  java
  • 2019牛客多校第五场

    digits

    题意

    给定一个n,要构造一个数,本身是n个倍数,每一位的数加起来也是n的倍数。

    分析

    输出n个n即可,显然可以整除得到1..0..1..0..1,而且无论每一位上的数是什么,个数都是n个倍数,因此和可以整除n。

    代码

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

    B generator 1

    题意

    广义斐波那契数列求第n项。

    分析

    • 使用矩阵快速幂加速递推,但是指数很大,无法变成二进制来进行快速幂,只能使用十进制的快速幂。
    • 十进制快速幂其实就是对于大指数来说,像普通的字符串转大数的过程模拟一遍即可,比如字符串转大数是t=t*10+s[i]-'0',在快速幂这里,因为是在指数位置,所以是先t=Pow(t,10),然后t=t*Mul(x,s[i]-'0'),即乘法变为幂运算,加法变为乘法。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e6+50;
    char s[N];
    ll mod;
    struct Mat{
        ll a[2][2];
        void init(){
            memset(a,0,sizeof(a));
        }
        void print(){
            for(int i=0;i<2;i++){
                for(int j=0;j<2;j++){
                    printf("%d ",a[i][j]);
                }
                printf("
    ");
            }
        }
    };
    Mat mul(Mat a,Mat b){
        Mat ans;
        ans.init();
        for(int i=0;i<2;i++){
            for(int j=0;j<2;j++){
                for(int k=0;k<2;k++){
                    ans.a[i][j]=(ans.a[i][j]+a.a[i][k]*b.a[k][j])%mod;
                }
            }
        }
        return ans;
    }
    Mat Pow(Mat a,ll n){
        Mat ans;
        ans.init();
        ans.a[0][0]=ans.a[1][1]=1;
        while(n){
            if(n%2){
                ans=mul(ans,a);
            }
            a=mul(a,a);
            n/=2;
        }
        return ans;
    }
    ll X0,X1,a,b;
    int main(void){
        // freopen("in.txt","r",stdin);
        scanf("%lld%lld%lld%lld",&X0,&X1,&a,&b);
        scanf("%s%lld",s,&mod);
        Mat tr;
        tr.init();
        tr.a[0][1]=1;
        tr.a[1][0]=b;
        tr.a[1][1]=a;
        Mat ans;
        ans.init();
        ans.a[0][0]=1;
        ans.a[1][1]=1;
        int len=strlen(s);
        for(int i=0;i<len;i++){
            ans=Pow(ans,10ll);
            ans=mul(ans,Pow(tr,s[i]-'0'));
        }
        Mat b;
        b.init();
        b.a[0][0]=X0;
        b.a[1][0]=X1;
        ans=mul(ans,b);
        printf("%lld
    ",ans.a[0][0]);
        return 0;
    }
    

    H subsequence 2

    题意

    要构造一个长度为n的字符串,有m种字符,给出两两之间的关系,和该字符串只含这两个字符的形式。

    分析

    • 要构造出字符串显然需要字符之间的位置关系,对于每个关系,我们将相邻的字符连一条有向边,拓扑排序即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e6+50;
    int n,m,len;
    char t[N],s[N];
    struct Edge{
        int v,next;
    }edge[N*20];
    int k;
    int cnt,head[N];
    int ind[N],tp[N];
    bool flag;
    int pos[26][N],ac[26];
    int num;
    void init(){
        cnt=0;
        memset(head,-1,sizeof(head));
    }
    void add(int u,int v){
        edge[cnt]=Edge{v,head[u]};
        head[u]=cnt++;
        ind[v]++;
    }
    void topo(){
        queue<int> q;
        for(int i=1;i<=num;i++){
            if(!ind[i]){
                q.push(i);
                tp[k++]=i;
            }
        }
        int cnt=0;
        while(!q.empty()){
            int u=q.front();
            q.pop();
            cnt++;
            for(int i=head[u];i!=-1;i=edge[i].next){
                int v=edge[i].v;
                ind[v]--;
                if(!ind[v]){
                    q.push(v);
                    tp[k++]=v;
                }
            }
        }
        if(cnt!=num){
            flag=true;
        }
    }
    map<int,char> mp;
    int main(void){
        // freopen("in.txt","r",stdin);
        scanf("%d%d",&n,&m);
        init();
        memset(pos,-1,sizeof(pos));
        for(int i=0;i<m*(m-1)/2;i++){
            scanf("%s",t);
            scanf("%d",&len);
            if(!len){
                continue;
            }
            scanf("%s",s);
            memset(ac,0,sizeof(ac));
            int idx=s[0]-'a';
            ac[idx]++;
            if(pos[idx][ac[idx]]==-1){
                pos[idx][ac[idx]]=++num;
            }
            int p=pos[idx][ac[idx]];
            mp[p]=s[0];
            for(int j=1;j<len;j++){
                int idx=s[j]-'a';
                ac[idx]++;
                if(pos[idx][ac[idx]]==-1){
                    pos[idx][ac[idx]]=++num;
                }
                int tt=pos[idx][ac[idx]];
                mp[tt]=s[j];
                add(p,tt);
                p=tt;
            }
        }
        topo();
        if(flag || k!=n){
            printf("-1
    ");
        }else{
            for(int i=0;i<k;i++){
                printf("%c",mp[tp[i]]);
            }
            printf("
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    Python 函数 -range()
    Python 函数 -xrange()
    Python 函数 -globals()
    Python 函数-max()
    Python 函数 -hasattr()
    Python 函数 memoryview()
    Python函数 hash()
    QAQ
    Õ() Big-O-notation
    一道有趣的条件概率题
  • 原文地址:https://www.cnblogs.com/zxcoder/p/11326817.html
Copyright © 2011-2022 走看看