zoukankan      html  css  js  c++  java
  • 2020/11/03 模拟赛 偶数

    Description

    牛牛喜欢偶数,他定义一种新的“偶数”为:(在十进制下,去掉前导零)数字的位 数为偶数,且数字前一半和后一半完全一致。比如 121121、12341234 是“偶 数”,而 111、121212 不是“偶数”。 对于一个“偶数”,牛牛可以在这个“偶数”后继续添加数字,使得它成为新的“偶 数”。比如, 121121 可以在后面添加数字,使之变成 1211212112 成为新的 “偶数”。牛牛总是想添加最少的数字获得新的“偶数”。可以证明添加的方式是唯 一的。 对于任何一个“偶数”,牛牛都可以通过上述的方式产生新的“偶数”,这个新的 “偶数”继续产生下一个新的“偶数”,直到这个“偶数”的位数超过任意给定的正整 数 $n$ 为止。之后,牛牛会多次询问你,这个最终的“偶数”的第 $l$ 位到第 $r$ 位$1 leq l leq r leq n$组成的整数 模 $998244353$ 后是多少。

    Solution

    题中要求的偶数是前一半与后一半完全相同的数,并可以复制给出的原数使其不断扩展成一个新的偶数,最后求超过给定位数的偶数的指定数位区间所显示的数

    对于一个偶数,新扩展出的偶数一定是它加上它的最小周期

    不断如此处理,直至长度超过给定长度

    维护一些值

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int T,nxt[100005],q,lim;
    long long fs[100005],n,m,len[100],f[100],ten[100];
    const long long mod=998244353;
    char s[100005];
    inline long long read()
    {
        long long w=0,f=1;
        char ch=0;
        while(ch<'0'||ch>'9')
        {
            if(ch=='-') f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
        return w*f;
    }
    void getNext()
    {
        int i=0,j=nxt[0]=-1;
        while(i<n)
        {
            while(j!=-1&&s[i]!=s[j]) j=nxt[j];
            nxt[++i]=++j;
        }
    }
    long long ksm(long long a,long long p)
    {
        long long ret=1;
        while(p)
        {
            if(p&1) (ret*=a)%=mod;
            (a*=a)%=mod,p>>=1;
        }
        return ret;
    }
    long long sol(long long m)
    {
        long long sum=0,ret=0;
        for(int i=lim;i>=0;i--)
        {
            if(sum+len[i]<=m)
            {
                ret=(ret*ten[i]%mod+f[i])%mod;
                sum+=len[i];
            }
        }
        ret=(ret*ksm(10,m-sum)%mod+fs[m-sum])%mod;
        return ret;
    }
    int main()
    {
        T=read();
        for(;T;T--)
        {
            scanf("%s",s);
            n=strlen(s)/2;
            getNext();
            for(int i=1;i<=n;i++) fs[i]=(fs[i-1]*10+s[i-1]-'0')%mod;
            m=read(),q=read();
            len[0]=n-nxt[n],f[0]=fs[len[0]];
            len[1]=n,f[1]=fs[n];
            for(int i=2;i<100;i++)
            {
                len[i]=len[i-1]+len[i-2];
                f[i]=(f[i-1]*ksm(10,len[i-2])%mod+f[i-2])%mod;
                if(len[i]>=m)
                {
                    lim=i;break;
                }
            }
            for(int i=0;i<=lim;i++) ten[i]=ksm(10,len[i]);
            for(int i=1;i<=q;i++)
            {
                long long l=read(),r=read();
                printf("%lld
    ",(sol(r)-sol(l-1)*ksm(10,r-l+1)%mod+mod)%mod);
            }
        }
        return 0;
    }
    偶数
  • 相关阅读:
    luogu P3368 【模板】树状数组 2
    dp
    vijos 羽毛
    luogu tyvj 纪念品分组
    codevs 1259 最大正方形子矩阵 WD
    python 序列化之pickle模块 json模块
    python 类的进阶
    python 面向对象与类的基本知识
    python 异常处理
    python time模块 sys模块 collections模块 random模块 os模块 序列化 datetime模块
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/13984378.html
Copyright © 2011-2022 走看看