此题为逆元的应用,直接求的话会超时
大体题意:
给你个字符串并且告诉你n个查询。
每个查询 有起点和终点,求从起点x到终点y (ASCII码-28)乘积之和对mod 取模的结果!
很明显 肯定要先预处理使得sum[i]表示从第一个点到第i个点的乘积之和!
然后通过sum[y]/ sum[x-1] 就是答案!
但是要通过乘法逆元来得到!
就是sum[y]乘以 sum[x-1]的逆元 来算结果!
因为mod 是素数。
所以逆元就是sum[x-1] ^ (mod-2)%mod
通过快速幂算得即可!
最后结果取模一下就可以了!
#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;
}