2016"百度之星" - 资格赛(Astar Round1) Problem A

保存前缀乘,询问的时候输出c[ri]/c[li-1]即可,因为是除法,所以计算一下c[li-1]的逆元。

#include <stdio.h>
#include <math.h>
#include<cstring>
#include<cmath>
#include<map>
#include<string>
#include<algorithm>
using namespace std;

long long mod=9973;
char s[100000+10];
long long num[100000+10];

long long extend_gcd(long long a,long long b,long long &x,long long &y)
{
    if(a==0&&b==0) return -1;
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    long long d=extend_gcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}

long long mod_reverse(long long a,long long n)
{
    long long x,y;
    long long d=extend_gcd(a,n,x,y);
    if(d==1) return (x%n+n)%n;
    else return -1;
}

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        scanf("%s",s);
        int len=strlen(s);
        num[0]=1;
        for(int i=0; s[i]; i++) num[i+1]=s[i]-28;
        for(int i=1; i<=len; i++) num[i]=(num[i]*num[i-1])%mod;
        for(int i=1; i<=n; i++)
        {
            int li,ri;
            scanf("%d%d",&li,&ri);
            long long NI=mod_reverse(num[li-1],mod);
            long long ans=(num[ri]*NI)%mod;
            printf("%lld\n",ans);
        }
    }
    return 0;
}

 

posted @ 2016-05-15 09:53  Fighting_Heart  阅读(138)  评论(0编辑  收藏  举报