• HDU4669_Mutiples on a circle


    题目的意思是给你一些数字a[i](首位相连),现在要你选出一些连续的数字连续的每一位单独地作为一个数位。现在问你有多少种选择的方式使得选出的数字为k的一个倍数。

    其实题目是很简单的。由于k不大(200),总共的数字个数为50000,所以我们对于当前走到的每一个数字最多的状态数目也只有50000*200个。

    同时由于是循环的,我们可以使长度增倍,这样就可以保证序列是循环的了。

    不过注意,增倍后空间是开不下的,所以需要使用循环的滚动数组。

    同时注意递推的细节,还有有的a[i]不止一位数,不能直接取模。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define maxn 50050
    typedef long long ll;
    using namespace std;
    
    int a[2*maxn],f[2*maxn],n,m,k,tep,cur,w[2*maxn];
    int s[maxn][205];
    ll ans;
    
    void init_(int x)
    {
        for (int i=0; i<k; i++) s[x][i]=0;
    }
    
    int count(int x)
    {
        if (x<10) return 1;
        if (x<100) return 2;
        if (x<1000) return 3;
        return 4;
    }
    
    int get(int x)
    {
        if (x==1) return 10;
        if (x==2) return 100%k;
        if (x==3) return 1000%k;
        return 10000%k;
    }
    
    int power(int x,int y)
    {
        int tot=1;
        while (y)
        {
            if (y&1) tot=(tot*x)%k;
            y>>=1;
            x=(x*x)%k;
        }
        return tot;
    }
    
    int main()
    {
        while (scanf("%d%d",&n,&k)!=EOF)
        {
            ans=0;
            w[0]=0,f[0]=0;
            for (int i=1; i<=n; i++)
            {
                scanf("%d",&a[i]);
                a[i+n]=a[i];
                w[i]=count(a[i]);
                w[i+n]=count(a[i+n]);
            }
            for (int i=1; i<=2*n; i++) f[i]=(f[i-1]*get(w[i])+a[i])%k;
            for (int i=1; i<=2*n; i++) w[i]+=w[i-1];
            for (int i=1; i<=n; i++)
            {
                init_(i);
                s[i][a[i]%k]++;
                for (int j=0; j<k; j++) s[i][(get(w[i]-w[i-1])*j+a[i])%k]+=s[i-1][j];
            }
            for (int i=n+1; i<=2*n; i++)
            {
                int qq=i-n-1;
                if (qq==0) qq=n;
                init_(i-n);
                s[i-n][a[i]%k]++;
                for (int j=0; j<k; j++) s[i-n][(get(w[i]-w[i-1])*j+a[i])%k]+=s[qq][j];
                cur=(f[i-n-1]*power(10,w[i]-w[i-n-1]))%k;
                cur=((f[i]-cur)%k+k)%k; 
                s[i-n][cur]--; 
                ans+=s[i-n][0];
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    如有转载,请注明出处(http://www.cnblogs.com/lochan)
  • 相关阅读:
    Python time gmtime()方法
    背包DP整理
    hdu 1561 The more, The Better
    Eclipse无法打开提示could not open jvm.cfg错误
    Http协议
    反射类
    xml——dom&sax解析、DTD&schema约束
    XML、DTD约束
    java——final、权限修饰符
    java——接口、多态性、对象转型
  • 原文地址:https://www.cnblogs.com/lochan/p/3446851.html
Copyright © 2020-2023  润新知