费马小定理

https://vjudge.net/problem/HDU-5685

题意:给一个公式  求字符串的hash值  

然后给你一个完整字符串  a  b 两点  然后输出a b子串的hash值

 

思路:子串, 有公式 ,很容易想到前缀积  因为利用前缀积可以表示任意一个子串

但是乘法,还累乘  肯定爆    所以我们只能保存mod后的值

现在有了pre【】    求a b子串  原本就是用  b/(a - 1) % mod 得到结果, 但因为以上因素

 

引入费马小定律  x是任意整数, p是一个质数(2,3,5,7,11,13)

x^(p-1) % p  == 1 % p

推出 x^(p-2) %p == x^(-1) %p

即x^(p-2) 等价于 x^(-1)

 

再回来看 b/(a - 1) % mod    不就是 【(b%mod)*((a-1)%mod)】%mod

可以发现(b%mod)等于pre【b】     (a-1)%mod 等于 pre【a - 1】 等于pre【a - 1】的(p - 2) 次方

直接快速幂

//因为要问子串的的hash值
//先求前缀积 但是数很大,前缀积显然只能存下%9973后得值
//但有:(A/B)%M=(A%M*(B^-1%M))%M,A%M显然就是pre[A],B的逆对M取余就是qpow(B,M-2,M),快速幂模之即可

#include<iostream>
#include<cstring>
#include<cmath>
#include<string>
#include<map>
#include<vector>
#include<set>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<functional>

using namespace std;
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
#define LL long long
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
//#define mp make_pair
#define pb push_back
#define ULL unsigned LL
#define mem(a, b) memset(a, b, sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define mod 9973
//#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);

const int maxn = 1e5 + 100;
int pre[maxn];

int qpow(int a, int b) {
	int res = 1;
	int temp = a;
	while (b) {
		if (b & 1) {
			res *= temp;
			res %= mod;
		}
		temp *= temp;
		temp %= mod;
		b >>= 1;
	}
	return res;
}
int main() {
	ios;
	int n;
	while (cin >> n) {
		string s;
		cin >> s;
		pre[0] = 1;
		for (int i = 0; i < s.size(); ++i) {
			pre[i + 1] = pre[i] * int(s[i] - 28) % mod;
		}
		int a, b;
		while (n--) {
			cin >> a >> b;
			//b/(a - 1)  % mod
			//转化成(pre【b】* (a - 1)的p-2次方%mod)%mod
			int ans = pre[b] * qpow(pre[a - 1], mod - 2) % mod;
			cout << ans << endl;
		}
		
		
		
	}

	return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值