Problem A
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
H(s)=∏?i=1?i≤len(s)??(S?i???28) (mod 9973)
其实要求区间[a,b]的哈希值,可以转化为[0,b]的哈希值/[0,a-1]的哈希值
首先[0,b]的哈希值和[0,a]的哈希值是很好求的,利用ans[i+1]=ans[i]*(s[i]-28)%mod即可
但是因为乘积值是经过取模的,对除法来说,取模运算是不满足同余的
这个时候就会想到乘法逆元,幸好早已备好乘法逆元的模板,剩下的就是贴模板了
题目链接→HDU 5685 Problem A
/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 100005;
const int M = 40;
const int inf = 100000000;
const int mod = 9973;
char s[N];
int ans[N];
__int64 Quick_Mod(int a,int b)//快速幂
{ __int64 res = 1,term = a % mod; while(b) { if(b & 1) res = (res * term) % mod; term = (term * term) % mod; b >>= 1; } return res;
}
int main()
{int n,i,j,a,b;while(~scanf("%d",&n)){scanf("%s",s);ans[0]=1;ans[1]=(s[0]-28)%mod;for(i=1;s[i]!='\0';i++)ans[i+1]=ans[i]*(s[i]-28)%mod;for(i=0;i<n;i++){scanf("%d%d",&a,&b);printf("%d\n",(ans[b]*Quick_Mod(ans[a-1],mod-2))%mod);//计算(ans[b]/ans[a-1])%mod }}return 0;
}
菜鸟成长记