zoukankan      html  css  js  c++  java
  • L The Digits String(没有写完,有空补)

    链接:https://ac.nowcoder.com/acm/contest/338/L
    来源:牛客网

      Consider digits strings with length n, how many different strings have the sum of digits are multiple of 4?

    输入描述:

    There are several test cases end with EOF. For each test case, there is an integer in one line: n, the length of the digits string. (1≤n≤1,000,000,000).

    输出描述:

    For each case, output the number of digits strings with length n have the sum of digits are  multiple of 4 in one line. The numbers maybe very large, you should output the result modular 2019.
    示例1

    输入

    复制
    1
    2
    3
    4

    输出

    复制
    3
    25
    249
    479

    题目大意
    • 求长度为n的数字串中,有多少个这样数字串,其数字
    之和是4的倍数(包括0)
    • 输入:每组测试数据一行,包含一个正整数n(1 ≤ c≤ 109)
    • 输出:对于每组测试数据,输出一行,包含一个整数, 表示有多少个这样数字串,其数字之和是4的倍数(包 括0)。因为这个结果很大,所以将值模2019输出
    
    • 本题快速幂,复杂度为O(logn)。标程在1000组测试 数据下的运行时间约为60毫秒(第二标程运行时间约 30毫秒)。建议时间限制为1秒,空间限制为64M。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <cfloat>
    #include <climits>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <list>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <algorithm>
    #include <bitset>
    using namespace std;
    
    #define LL long long
    const int matrix_size = 4;
    const int MOD = 2019;
    
    int add(int a, int b)
    {
        a += b;
        if(a >= MOD)
        {
            return a - MOD;
        }
        return a;
    }
    
    struct Matrix
    {
        int size;
        int num[matrix_size][matrix_size];
    
        void operator=(const Matrix &m)
        {
            for(int i = 0; i < size; ++i)
            {
                memcpy(num[i], m.num[i], sizeof(int) * size);
            }
        }
    
        void Init()
        {
            for(int i = 0; i < size; ++i)
            {
                memset(num[i], 0, sizeof(int) * size);
                num[i][i] = 1;
            }
        }
    
        void Set()
        {
            size = 4;
            memset(num, 0, sizeof(num));
            for(int j = 0; j < 4; ++j)
            {
                for(int i = 0; i < 10; ++i)
                {
                    ++num[(j + i) % 4][j];
                }
            }
        }
    
        void operator*=(const Matrix &m)
        {
            static Matrix ans;
            ans.size = size;
            for(int i = 0; i < size; ++i)
            {
                for(int j = 0; j < size; ++j)
                {
                    ans.num[i][j] = 0;
                    for(int k = 0; k < size; ++k)
                    {
                        ans.num[i][j] = add(ans.num[i][j], (LL)num[i][k] * m.num[k][j] % MOD);
                    }
                }
            }
            (*this) = ans;
        }
    
        void fast_pow(LL n)
        {
            static Matrix ans;
            ans.size = size;
            for(ans.Init(); n != 0; n >>= 1)
            {
                if((n & 1) == 1)
                {
                    ans *= (*this);
                }
                (*this) *= (*this);
            }
            (*this) = ans;
        }
    };
    
    int n;
    Matrix m;
    
    int main()
    {
    #ifdef Dmaxiya
        freopen("test.txt", "r", stdin);
    #endif // Dmaxiya
        ios::sync_with_stdio(false);
    
        while(scanf("%d", &n) != EOF)
        {
            m.Set();
            m.fast_pow(n);
            printf("%d
    ", m.num[0][0]);
        }
    
        return 0;
    }
    View Code

     标答

    •#include <stdio.h>#define M 2019#define L 4#define LP(i) for(i=0;i<L;++i)void Product(int x[L][L],int y[L][L],int z[L][L]){
    
    •    int i,j,k,w[L][L]={0};
    
    •    LP(i)LP(j)LP(k)w[i][j]=(w[i][j]+x[i][k]*y[k][j])%M;
    
    •    LP(i)LP(j)z[i][j]=w[i][j];}
    
    •
    
    •void FPow(int n,int r[L][L]){
    
    •    int i,j,A[L][L]={{3,2,2,3},{3,3,2,2},{2,3,3,2},{2,2,3,3}};
    
    •    LP(i)LP(j)r[i][j]=i==j?1:0;
    
    •while(n){
    
    •if(n&1)Product(r,A,r);
    
    •Product(A,A,A);
    
    •    n>>=1;}}
    
    
    •int cal(int n){
    
    •int r[L][L];
    
    •FPow(n,r);
    
    •    return    (3*r[0][0]+3*r[0][1]+2*r[0][2]+2*r[0][3])%M;}
    
    •
    
    •int main(){
    
    •int n;
    
    •while(scanf("%d",&n)!=EOF&&n>0)
    
    •printf("%d
    ",cal(n-1));
    
    •return 0;}
    View Code
    解题思路(续)
    • 矩阵
    • 3 2 2 33 3 2 22 3 3 22 2 3 3
    • 有四个特征根,分别是0,101+i,1-i;
    • 所以an=x10n+ycos(nπ/4)+zsin(nπ/4),根据
    a1=3,a2=25,a3=249,可得:
    • an=(10n+2sqrt(2)ncos(nπ/4))/4;
    • 同样快速幂求得答案。
    •#include <stdio.h>#define M 2019int rt[2][32],et[8]={2,2,0,-4,-8,-8,0,16};
    •int FPow(int f,int n){
    •    int r=1,m=0;
    •while(n){
    •    if(n&1)r=(r*rt[f][m])%M;
    •    m++;
    •    n>>=1;}
    •return r;}
    •
    •int cal(int n){
    •int r1,r2;
    •    r1=FPow(0,n);
    •    r2=((FPow(1,n/8)*et[n%8])%M+M)%M;
    •    return ((r1+r2)*505)%M;
    •    }
    •int main(){
    •int n,i;
    •    rt[0][0]=10;rt[1][0]=16;
    •    for(i=1;i<32;++i){
    •    rt[0][i]=(rt[0][i-1]*rt[0][i-1])%M;
    •    rt[1][i]=(rt[1][i-1]*rt[1][i-1])%M;}
    •while(scanf("%d",&n)!=EOF&&n>0)
    •printf("%d
    ",cal(n));
    •return 0;}
    View Code

    STZG的代码

  • 相关阅读:
    杭电1176解答免费馅饼
    Locust 关联
    Locust 参数化
    Locust 介绍篇
    Locust 集合点
    Locust 其他协议
    团队项目需求分析报告
    第一次个人编程作业
    团队项目选题报告
    第一次软工作业
  • 原文地址:https://www.cnblogs.com/DWVictor/p/10230021.html
Copyright © 2011-2022 走看看