2016"百度之星"

Problem A

 
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
Problem Description

度熊手上有一本字典存储了大量的单词,有一次,他把所有单词组成了一个很长很长的字符串。现在麻烦来了,他忘记了原来的字符串都是什么,神奇的是他竟然记得原来那些字符串的哈希值。一个字符串的哈希值,由以下公式计算得到:

H(s)=prod_{i=1}^{ileq len(s)}(S_{i}-28) (mod 9973)H(s)=i=1ilen(s)​​(Si​​28) (mod 9973)

S_{i}Si​​代表 S[i] 字符的 ASCII 码。

请帮助度熊计算大字符串中任意一段的哈希值是多少。

Input

多组测试数据,每组测试数据第一行是一个正整数NN,代表询问的次数,第二行一个字符串,代表题目中的大字符串,接下来NN行,每行包含两个正整数aa和bb,代表询问的起始位置以及终止位置。

1leq Nleq 1,0001N1,000

1leq len(string)leq 100,0001len(string)100,000

1leq a,bleq len(string)1a,blen(string)

Output

对于每一个询问,输出一个整数值,代表大字符串从 aa 位到 bb 位的子串的哈希值。

Sample Input
2
ACMlove2015
1 11
8 10
1
testMessage
1 1
Sample Output
6891
9240
88
思路,简单的前缀积,由于要取模需要逆元;
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<vector>
#include<list>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define mod 9973
#define inf 999999999
#define esp 0.00000000001
//#pragma comment(linker, "/STACK:102400000,102400000")
int scan()
{
    int res = 0 , ch ;
    while( !( ( ch = getchar() ) >= '0' && ch <= '9' ) )
    {
        if( ch == EOF ) return 1 << 30 ;
    }
    res = ch - '0' ;
    while( ( ch = getchar() ) >= '0' && ch <= '9' )
        res = res * 10 + ( ch - '0' ) ;
    return res ;
}
char a[100010];
int mul[100010];
void extend_Euclid(int a, int b, int &x, int &y)
{
    if(b == 0)
    {
        x = 1;
        y = 0;
        return;
    }
    extend_Euclid(b, a % b, x, y);
    int tmp = x;
    x = y;
    y = tmp - (a / b) * y;
}
int main()
{
    int x,y,z,i,t;
    while(~scanf("%d",&x))
    {
        scanf("%s",a);
        y=strlen(a);
        mul[0]=1;
        mul[1]=a[0]-28;
        for(i=1;i<y;i++)
        {
            mul[i+1]=mul[i]*(a[i]-28);
            mul[i+1]%=9973;
        }
        for(i=0;i<x;i++)
        {
            int l,r,ans;
            scanf("%d%d",&l,&r);
            int xx,yy;
            extend_Euclid(mul[l-1],9973,xx,yy);
            ans=(xx%mod+mod)%mod;
            ans*=mul[r];
            printf("%d
",ans%=mod);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/jhz033/p/5496346.html