度熊手上有一本字段儲存了大量的單詞,有一次,他把所有單詞組成了乙個很長很長的字串。現在麻煩來了,他忘記了原來的字串是什麼,神奇的是他竟然記得原來那些字串的雜湊值。乙個字串的雜湊值,由以下公式計算得到:
\(h(s)=\prod_^(s_-28)(mod 9973)\)
\(s_\)代表s[i]字元的ascii碼。
請版主度熊計算大字串中任意一段的雜湊值是多少。
多組測試資料,每組測試資料第一行是乙個正整數n,代表詢問的次數,第二行乙個字串,代表題目中的大字串,接下來n行,每行包含兩個正整數a和b,代表詢問的起始位置以及終止位置。
\(1\leq n\leq 1,000\)
\(1\leq len(string) \leq 100,000\)
\(1\leq a,b\leq len(string)\)
對於每乙個詢問,輸出乙個整數值,代表大字串從 a 位到 b 位的子串的雜湊值。
2
acmlove2015
1 11
8 10
1testmessage
1 1
6891
9240
88
#include#includeusing namespace std;
#define mod 9973 //要%的數
int inv[10000];//存放逆元的陣列
int pre[100005];//存放字首積
char s[100005];//存放字串
//快速冪,因為費馬小定理要求乙個數的(mod-2)次方
//a存放底數,b存放冪指數
int quickpow(int a,int b)
b>>=1;//b右移一位,相當於除以2
a=a*a%mod;//底數增大一倍
} return r;
}int main()
while(scanf("%d",&n)==1)
while(n--)
} return 0;
}
這道題就是求任意區間的字首積,因為是任意區間,所以採取的計算結果的方案是這樣的:
假如讓求a到b的字首積,我們就用從1到b的字首積除以從1到a-1的字首積,這樣就得到了a到b的字首積,問題是乙個除法的模運算很麻煩,模運算是不能加到括號裡的,但是如果變成乘法運算,那就可以把模運算加到括號裡了,這時候就要用到逆元了,這裡用的是用費馬小定理來求的逆元,如果要求a對mod的逆元,那就等於\(a^\) ,這時候就涉及到求乙個數的次方了,如果次方小還可以,但是次方太大的話,就會超時,這時,還會用到快速冪,這樣就能完美求出逆元了。
費馬小定理求逆元
求餘的概念 a b p a p b p p a b p a p b p p a b p a p b p p 為什麼要求逆元 對於一些題目,我們必須在中間過程中進行求餘,否則數字太大,電腦存不下,那如果這個算式中出現除法,我們是不是對這個算式就無法計算了呢?這時候就用到了逆元。費馬曾經說過 費馬小定理...
費馬小定理 求乘法逆元
p3811 模板 乘法逆元 includeusing namespace std inline void write long long x if x 9 write x 10 putchar x 10 0 long long qpow long long n,long long m,long lo...
乘法逆元 費馬小定理
我實在是太.才明白這個qwq 一 前置知識 定義1 給定正整數m,若用m除兩個整數a和b所得的餘數相同,稱a和b對模m同餘,記作a b mod m 並稱該式子為同余式 否則稱a和b對模m不同餘 二 乘法逆元 若整數b,p互質,並且b a,則存在乙個整數x,使得 a b a x mod p 稱x為b的...