zoukankan      html  css  js  c++  java
  • 【BZOJ 3326】[Scoi2013]数数

    题目描述

    Fish 是一条生活在海里的鱼,有一天他很无聊,就开始数数玩。他数数玩的具体规则是:

    1. 确定数数的进制B

    2. 确定一个数数的区间[L, R]

    3. 对于[L, R] 间的每一个数,把该数视为一个字符串,列出该字符串的每一个(连续的)子串对应的B进制数的值。

    4. 对所有列出的数求和。现在Fish 数了一遍数,但是不确定自己的结果是否正确了。由于[L, R] 较大,他没有多余精力去验证是否正确,你能写一个程序来帮他验证吗?

    输入输出格式

    输入格式:

    输入包含三行。

    第一行仅有一个数B,表示数数的进制。

    第二行有N +1 个数,第一个数为N,表示数L 在B 进制下的长度为N,接下里的N个数从高位到低位的表示数L 的具体每一位。

    第三行有M+ 1 个数,第一个数为M,表示数R 在B 进制下的长度为M,接下里的M个数从高位到低位的表示数R 的具体每一位。

    输出格式:

    输出仅一行,即按照Fish 数数规则的结果,结果用10 进制表示,由于该数可能很大,输出该数模上20130427的模数。

    输入输出样例

    输入样例#1: 复制
    10
    3 1 0 3
    3 1 0 3
    输出样例#1: 复制
    120
    

    说明

    【样例解释】

    [103, 103] 之间仅有数103,该数的所有子串包括1, 10, 103, 0, 03, 3,其和为120。

    【数据范围与约定】

    20% 数据,0 <= R <= L <= 10^5。

    50% 数据,2 <= B <= 1000,1 <= N,M <= 1000。

    100% 数据,2 <= B <= 10^5,1 <= N,M <= 10^5。

    题解

      我不会

      题解的思路明白,但代码根本看不懂

      米娜自己去看好了……我实在无能为力……

      这里

     1 //minamoto
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<iostream>
     6 #define ll long long
     7 using namespace std;
     8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     9 char buf[1<<21],*p1=buf,*p2=buf;
    10 inline int read(){
    11     #define num ch-'0'
    12     char ch;bool flag=0;int res;
    13     while(!isdigit(ch=getc()))
    14     (ch=='-')&&(flag=true);
    15     for(res=num;isdigit(ch=getc());res=res*10+num);
    16     (flag)&&(res=-res);
    17     #undef num
    18     return res;
    19 }
    20 const int N=100005,mod=20130427;
    21 int n,m,B,L[N],R[N];
    22 ll SB[N],S[N],a[N][2],s[N][2],ss[N][2],sl[N][2];
    23 int solve(int *p,int l){
    24     memset(a,0,sizeof(a));
    25     memset(s,0,sizeof(s));
    26     memset(ss,0,sizeof(ss));
    27     memset(sl,0,sizeof(sl));
    28     a[l][0]=1;
    29     for(int i=l-1;~i;--i){
    30         int c=(i==l-1?0:B);
    31         a[i][0]=a[i+1][0];
    32         a[i][1]=(c-1+a[i+1][1]*B+a[i+1][0]*p[i])%mod;
    33         sl[i][0]=sl[i+1][0]+a[i+1][0];
    34         sl[i][1]=(c-1+sl[i][0]*p[i]+
    35                     (sl[i+1][1]+a[i+1][1])*B)%mod;
    36         ss[i][0]=(ss[i+1][0]*B+p[i]*sl[i][0])%mod;
    37         ss[i][1]=(S[c]+ss[i+1][0]*B*p[i]+S[p[i]]*sl[i][0]+
    38                     ss[i+1][1]*B%mod*B+
    39                     S[B]*(sl[i+1][1]+a[i+1][1]))%mod;
    40         s[i][0]=(s[i+1][0]+ss[i][0])%mod;
    41         s[i][1]=(s[i+1][0]*p[i]+s[i+1][1]*B+ss[i][1])%mod;
    42     }
    43     return (s[0][0]+s[0][1])%mod;
    44 }
    45 int main(){
    46     //freopen("testdata.in","r",stdin);
    47     B=read();SB[0]=1;
    48     for(int i=0;i<N-1;++i) SB[i+1]=(SB[i]*B+1)%mod;
    49     S[0]=0;
    50     for(int i=0;i<B;++i) S[i+1]=(S[i]+i)%mod;
    51     n=read();
    52     for(int i=0;i<n;++i) L[n-i-1]=read();
    53     for(int i=0;i<n;++i){
    54         if(L[i]>0){--L[i];break;}
    55         L[i]=B-1;
    56     }
    57     if(!L[n-1]) --n;
    58     m=read();
    59     for(int i=0;i<m;++i) R[m-i-1]=read();
    60     printf("%d
    ",(solve(R,m)-solve(L,n)+mod)%mod);
    61     return 0;
    62 }
  • 相关阅读:
    poj 1035 (Spell checker )
    poj 3080 (暴力 strstr)
    kmp 模版
    匈牙利算法模版
    poj 1274 The Perfect Stall (最大匹配)
    hdu 1083 Courses(二分图 )
    pku 3363(内部测试赛)
    Linux 下联网脚本文件
    Qt 多国语言
    引用和引用参数
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9541251.html
Copyright © 2011-2022 走看看