HDU4436 后缀数组
来源:互联网 发布:android网络定位源码 编辑:程序博客网 时间:2024/06/08 10:23
str2int
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 434 Accepted Submission(s): 140
Problem Description
In this problem, you are given several strings that contain only digits from '0' to '9', inclusive.
An example is shown below.
101
123
The set S of strings is consists of the N strings given in the input file, and all the possible substrings of each one of them.
It's boring to manipulate strings, so you decide to convert strings in S into integers.
You can convert a string that contains only digits into a decimal integer, for example, you can convert "101" into 101, "01" into 1, et al.
If an integer occurs multiple times, you only keep one of them.
For example, in the example shown above, all the integers are 1, 10, 101, 2, 3, 12, 23, 123.
Your task is to calculate the remainder of the sum of all the integers you get divided by 2012.
An example is shown below.
101
123
The set S of strings is consists of the N strings given in the input file, and all the possible substrings of each one of them.
It's boring to manipulate strings, so you decide to convert strings in S into integers.
You can convert a string that contains only digits into a decimal integer, for example, you can convert "101" into 101, "01" into 1, et al.
If an integer occurs multiple times, you only keep one of them.
For example, in the example shown above, all the integers are 1, 10, 101, 2, 3, 12, 23, 123.
Your task is to calculate the remainder of the sum of all the integers you get divided by 2012.
Input
There are no more than 20 test cases.
The test case starts by a line contains an positive integer N.
Next N lines each contains a string consists of one or more digits.
It's guaranteed that 1≤N≤10000 and the sum of the length of all the strings ≤100000.
The input is terminated by EOF.
The test case starts by a line contains an positive integer N.
Next N lines each contains a string consists of one or more digits.
It's guaranteed that 1≤N≤10000 and the sum of the length of all the strings ≤100000.
The input is terminated by EOF.
Output
An integer between 0 and 2011, inclusive, for each test case.
Sample Input
510112309000 1234567890
Sample Output
202
倍增算法求后缀数组,然后求height 数组去重,然后用部分和求和,其中要减去偏移量,然后Ok!
#include <iostream>#include <cstring>#include <cstdio>using namespace std;#define maxn 200000const int mod=2012;int wa[maxn],wb[maxn],wv[maxn],wss[maxn];int Sa[maxn];int height[maxn];int rank[maxn];int Pow[maxn];int V[maxn];int T[maxn];char s[maxn];int Len[maxn];int S[maxn];int P[maxn];int arrive[maxn];int cmp(int *r,int a,int b,int l){ return r[a]==r[b]&&r[a+l]==r[b+l];}void da(int *r,int *sa,int n,int m){ int i,j,p,*x=wa,*y=wb,*t; for (i=0;i<m;i++) wss[i]=0; for (i=0;i<n;i++) wss[x[i]=r[i]]++; for (i=1;i<m;i++) wss[i]+=wss[i-1]; for (i=n-1;i>=0;i--) sa[--wss[x[i]]]=i; for (j=1,p=1;p<n;j*=2,m=p) { for (p=0,i=n-j;i<n;i++) y[p++]=i; for (i=0;i<n;i++) if (sa[i]>=j) y[p++]=sa[i]-j; for (i=0;i<n;i++) wv[i]=x[y[i]]; for (i=0;i<m;i++) wss[i]=0; for (i=0;i<n;i++) wss[wv[i]]++; for (i=1;i<m;i++) wss[i]+=wss[i-1]; for (i=n-1;i>=0;i--) sa[--wss[wv[i]]]=y[i]; for (t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) { x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; } }}void calheight(int *r,int *sa,int n){ int i,j,k=0; for (i=0;i<n;i++) rank[sa[i]]=i; for (i=0;i<n;i++) { if (rank[i]) { for (k!=0?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++); } height[rank[i]]=k; }}int get(int l,int r){ if (l>r) return 0; int ans=(T[r+1]-T[l]); ans%=mod; ans-=V[l]*Pow[r-l+1]; ans%=mod; if (ans<0) ans+=mod; return ans;}int main(){ int n; int len,val; Pow[1]=10; int i,j; for (i=2;i<200000;i++) Pow[i]=(Pow[i-1]+1)*10%mod; while(scanf("%d",&n)!=EOF) { len=val=0; for (i=0;i<n;i++) { scanf("%s",s); Len[i]=strlen(s); for (j=0;j<Len[i];j++) { S[len]=s[j]-'0'+1; val=(val*10+S[len]-1)%mod; V[len+1]=val; T[len+1]=(T[len]+val)%mod; P[len]=i; len++; } S[len]=11; val=(val*10+10)%mod; V[len+1]=val; T[len+1]=(T[len]+val)%mod; P[len]=i; len++; arrive[i]=len-2; } S[len-1]=0; da(S,Sa,len,12); calheight(S,Sa,len); int ans=0; for (i=0;i<len;i++) { if (S[i]%10!=1) { if (i+height[rank[i]]<=arrive[P[i]]) { ans+=get(i,arrive[P[i]])-get(i,i+height[rank[i]]-1); ans%=mod; if (ans<0) ans+=mod; } } } printf("%d\n",ans); } return 0;}
- HDU4436 后缀数组
- 后缀数组hdu4436(2012现场赛)
- hdu4436 后缀数组求不同数字的和
- hdu4436 str2int 后缀自动机 SAM
- hdu4436
- hdu4436 && cf#244D 后缀自动机
- 多串后缀自动机(hdu4436)
- [hdu4436]str2int
- 后缀树/后缀数组
- 后缀树 后缀数组
- 【后缀数组】后缀排序
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- C 语言细节
- 激光的安全等级简介
- 安装mysql,在./configure时出现错误:error: No curses/termcap library found的解决办法
- tomcat的编码设置(转)
- Windows socket编程 udp协议传送封装自定义帧
- HDU4436 后缀数组
- win7安装IIS及将网站发布到IIS上
- 黑马程序员----JAVA----面向对象小结(2)----
- loopup、计算字段如果是汉字字段,不能用TWideStringField!
- 设计模式之装饰者模式
- mac下安装automake
- 让Django支持数据库长连接(可以提高不少性能哦)
- Thinking In Java 第一天
- Plan Would Put a Bank in Every Browser