看题:http://bestcoder.hdu.edu.cn/contests/contest_show.php?cid=690
| Solved | Pro.ID | Title | Author | Source | (AC/Submit)Ratio |
| 5685 | Problem A | 2016"百度之星" - 资格赛(Astar Round1) | (215/533)40.34% | ||
| 5686 | Problem B | 2016"百度之星" - 资格赛(Astar Round1) | (150/424)35.38% | ||
| 5687 | Problem C | 2016"百度之星" - 资格赛(Astar Round1) | (187/532)35.15% | ||
| 5688 | Problem D | 2016"百度之星" - 资格赛(Astar Round1) | (226/315)71.75% | ||
| 5689 | Problem E | 2016"百度之星" - 资格赛(Astar Round1) | (36/72)50.00% |
A.题意:定义小写字母组成的字符串的哈希值,为(单个字母的ASCII码减去28)的乘积。给出长度最多为100000的字符串和最多1000次询问,每次询问[L,R]之间的字符串的哈希值。
题解:
有多种做法。
1.逆元 2.线段树 3.分块数组
1.逆元做法:因为每次求区间[L,R]乘积,可以用[1,R]乘([1,L-1]的逆元),就用预处理前缀积、前缀积逆元来搞,O(1)查询。好像代码写起来最简单。
2.线段树、块状数组做法:就做啊。线段树O(log(n))查询
我的是块状数组的,分sqrt大块,预处理大块,O(sqrt(n))查询,不是很推荐。
代码:
1 //#pragma comment(linker, "/STACK:102400000,102400000") 2 #include<cstdio> 3 #include<cmath> 4 #include<iostream> 5 #include<cstring> 6 #include<algorithm> 7 #include<cmath> 8 #include<map> 9 #include<set> 10 #include<stack> 11 #include<queue> 12 using namespace std; 13 14 #define MZ(array) memset(array, 0, sizeof(array)) 15 #define MF1(array) memset(array, -1, sizeof(array)) 16 #define MINF(array) memset(array, 0x3f, sizeof(array)) 17 #define REP(i,n) for(i=0;i<(n);i++) 18 #define FOR(i,x,n) for(i=(x);i<=(n);i++) 19 #define FORD(i,x,y) for(i=(x);i>=(y);i--) 20 #define RD(x) scanf("%d",&x) 21 #define RD2(x,y) scanf("%d%d",&x,&y) 22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z) 23 #define WN(x) printf("%d\n",x); 24 #define RE freopen("D.in","r",stdin) 25 #define WE freopen("huzhi.txt","w",stdout) 26 #define MP make_pair 27 #define PB push_back 28 #define PF push_front 29 #define PPF pop_front 30 #define PPB pop_back 31 typedef long long LL; 32 typedef unsigned long long ULL; 33 34 const double PI=acos(-1.0); 35 const double EPS=1e-10; 36 const int MAXN=1111; 37 const int MOD=9973; 38 int n; 39 int a[MAXN],b[MAXN]; 40 char s[111111]; 41 int l; 42 43 int q[111111]; 44 int ql; 45 46 void init() { 47 int i,j; 48 ql=sqrt(l); 49 int qll = l/ql; 50 REP(i,qll) { 51 q[i]=1; 52 int ed = (i+1)*ql - 1; 53 FOR(j,i*ql,ed) { 54 q[i]*=s[j]; 55 q[i]%=MOD; 56 } 57 } 58 } 59 60 int gank(int a,int b) { 61 if(a==b)return s[a]; 62 int sti=ceil(1.0*a/ql), edi=b/ql; 63 int st = sti*ql; 64 int ed = edi*ql; 65 int i; 66 int re=1; 67 if(ed<st) { 68 FOR(i,a,b) { 69 re*=s[i]; 70 re%=MOD; 71 } 72 } else { 73 FOR(i,a,st-1) { 74 re*=s[i]; 75 re%=MOD; 76 } 77 FOR(i,sti,edi-1) { 78 re*=q[i]; 79 re%=MOD; 80 } 81 FOR(i,ed,b) { 82 re*=s[i]; 83 re%=MOD; 84 } 85 } 86 return re; 87 } 88 89 int farm() { 90 int i; 91 l=strlen(s); 92 REP(i,l)s[i]-=28; 93 init(); 94 REP(i,n) { 95 WN(gank(a[i], b[i])); 96 } 97 } 98 99 int main() { 100 int i; 101 while(RD(n)!=EOF) { 102 scanf(" %s",s); 103 REP(i,n) { 104 RD2(a[i],b[i]); 105 a[i]--; 106 b[i]--; 107 } 108 farm(); 109 } 110 return 0; 111 }