HDU5685

来源:互联网 发布:淘宝评论给什么 编辑:程序博客网 时间:2024/06/15 19:11

Problem: 2016”百度之星” - 资格赛(Astar Round1)- A
Description: 中文题
Solution: 看到这个题第一感觉就是DP,dp[i]表示从1到i的哈希值的积MOD9973。那么我们要求a到b的哈希值=dp[b]/dp[a-1]%9973,这个式子如果dp[i]不取模的话就是正确的,但是它就是取模了,那么我们怎么办,这个时候当然是把除法转化成乘法,乘法取模相乘是没有影响的,那么就要用到dp[a-1]关于9973的乘法逆元了。于是这个题目就变成了一个求乘法逆元的题。求乘法逆元有两种方法,我都写下来了。
Code(C++):

#include <stdio.h>#include <string.h>const int M=100000+5;const int MOD=9973;int dp[M];char str[M];void init(char str[]){    dp[0]=1;    int len=strlen(str);    for(int i=1;i<=len;i++)        dp[i]=dp[i-1]*(str[i-1]-28)%MOD;}int cal(int x,int m,const int MOD){    int ans=1;    while(m){        if(m&1)            ans=ans*x%MOD;        m>>=1;        x=x*x%MOD;    }    return ans;}int gcd_extend(int a,int b,int &x,int &y){    if(!b){        x=1;        y=0;        return a;    }    int return_ans=gcd_extend(b,a%b,x,y);    int tmp=x;    x=y;    y=tmp-a/b*y;    return return_ans;}int cal2(int a,int b){    int x,y;    int Gcd=gcd_extend(a,b,x,y);    if(1%Gcd)        return -1;    x*=1/Gcd;    b/=Gcd;    b=b<0? -b:b;    int ans=x%b;    ans=ans<=0? ans+b:ans;    return ans;}int main(){    int N;    while(~scanf("%d",&N)){        scanf("%s",str);        init(str);        for(int i=0;i<N;i++){            int a,b;            scanf("%d%d",&a,&b);            if(a>b){                int tmp=a;                a=b;                b=tmp;            }            //int p=cal(dp[a-1],MOD-2,MOD);            int p=cal2(dp[a-1],MOD);            int ans=dp[b]*p%MOD;            printf("%d\n",ans);        }    }    return 0;}
0 0
原创粉丝点击