看题:http://bestcoder.hdu.edu.cn/contests/contest_show.php?cid=690

交题:http://acm.hdu.edu.cn/search.php?field=problem&key=2016%22%B0%D9%B6%C8%D6%AE%D0%C7%22+-+%D7%CA%B8%F1%C8%FC%A3%A8Astar+Round1%A3%A9&source=1&searchmode=source

Solved Pro.ID Title Author Source (AC/Submit)Ratio
2016百度之星 资格赛ABCDE 5685 Problem A   2016"百度之星" - 资格赛(Astar Round1) (215/533)40.34%
2016百度之星 资格赛ABCDE 5686 Problem B   2016"百度之星" - 资格赛(Astar Round1) (150/424)35.38%
2016百度之星 资格赛ABCDE 5687 Problem C   2016"百度之星" - 资格赛(Astar Round1) (187/532)35.15%
2016百度之星 资格赛ABCDE 5688 Problem D   2016"百度之星" - 资格赛(Astar Round1) (226/315)71.75%
2016百度之星 资格赛ABCDE 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 }
View Code

相关文章: