hdu 5685 Problem A (逆元)
来源:互联网 发布:雪梨淘宝店衣服质量 编辑:程序博客网 时间:2024/06/05 18:22
题目
题意:H(s)=∏i≤len(s)i=1(Si−28) (mod 9973),求一个字符串 子串(a 位到 b 位的)的哈希值。这个公式便是求字符串哈希值的公式,(字符的哈希值 = 字符的ASCII码 - 28),字符串的哈希值等于字符的哈希值的乘积( ∏ 这个就是累乘符号 )。
化简过后的题意就是求一段序列中的区间乘,由于询问次数比较多,直接求乘会超时。
就比如如下代码:
#include<stdio.h>char s[100010];int main(){ int T,a,b; while(~scanf("%d",&T)) { int ans = 1; scanf("%s",s+1); while(T--){ ans =1; scanf("%d%d",&a,&b); for(int i=a;i<=b;i++) ans = ans * (s[i] - 28 ) % 9973; printf("%d\n",ans); } } return 0;}所以用前缀乘的方法,例如:0到b 区间的哈希值,除以 0到a 区间的哈希值,得到的就是 a 到 b 的哈希值。
若用preMulit[i]表示前i个序列的前缀乘。要求[l,r]区间内的的数字全乘起来,那么用preMulit[r] / preMulit[l-1] 即可,考虑到取模的问题,用到逆元。
那么我就要问了,为什么考虑到取模的问题,就要用到逆元呢?而且什么是逆元呢?
(看链接)
接下来就是解题代码了
代码一:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;const ll maxn=100005;const ll mod=9973;ll sum[maxn],inv[maxn],re[maxn];char s[maxn];int main(){ inv[1]=1; for(int i=2;i<maxn;++i) { inv[i]=inv[mod%i]*(mod-mod/i)%mod; } int n; //freopen("shuju.txt","r",stdin); while(~scanf("%d",&n)) { scanf("%s",s+1); sum[0]=re[0]=1; for(int i=1;s[i]!=0;++i) { sum[i]=(sum[i-1]*(s[i]-28))%mod; re[i]=inv[sum[i]]; } for(int i=0;i<n;++i) { ll a,b; scanf("%lld%lld",&a,&b); ll tp=re[a-1]; printf("%I64d\n",(sum[b]*tp)%mod); } } return 0;}
代码二:(通过extgcd直接求)
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;const ll maxn=100005;const ll mod=9973;ll sum[maxn];char s[maxn];void extgcd(ll a,ll b,ll &x,ll &y){ if(!b) { x=1;y=0; return; } extgcd(b,a%b,y,x); y-=(a/b)*x;}ll inv(ll a,ll n){ ll d,x,y; extgcd(a,n,x,y); return (x+n)%n;}int main(){ int n; //freopen("shuju.txt","r",stdin); while(~scanf("%d",&n)) { scanf("%s",s+1); sum[0]=1; for(int i=1;s[i]!=0;++i) { sum[i]=(sum[i-1]*(s[i]-28))%mod; } for(int i=0;i<n;++i) { ll a,b; scanf("%lld%lld",&a,&b); ll tp=inv(sum[a-1],mod); printf("%I64d\n",(sum[b]*tp)%mod); } } return 0;}
阅读全文
0 0
- hdu 5685 Problem A【逆元】
- 【逆元】hdu 5685 Problem A
- hdu 5685 Problem A (逆元)
- hdoj 5685 Problem A(逆元)
- HDU 5685 Problem A
- HDU - 5685 Problem A
- hdu 5685 Problem A
- HDU 5685 Problem A
- Hdu 1576 A/B[乘法逆元]
- 乘法逆元 & hdu 1576 A/B
- HDU 1576 A/B 逆元
- HDU 5685 Problem A (求逆元)
- [HDU-5976] [Problem F](逆元+二分优化+数学分析)
- HDU Problem A
- hdu A + B problem
- hdu A simple problem
- A Math Problem HDU
- Kickstart Round A 2017 Problem A. Square Counting 公式、数论逆元、除法取模
- 再次使用construct 2制作游戏!
- mr refuse connection error
- 二分查找(非递归)
- 几个基础的小程序
- 最长回文
- hdu 5685 Problem A (逆元)
- 如何禁止极速版迅雷thunderplatform.exe启动
- 登录注册那些事儿(二)
- 六数码 关于EOF
- 顺序表
- Error:Could not run build action using Gradle installation解决办法
- Online Hard Example Mining
- 1-3 beanstalkd参数
- vue2.x 中如何获取 DOM