Prefix
Time Limit: 2000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 474 Accepted Submission(s): 150
For each test case, the first line contains one integer N(1≤N≤100000) . Then next N lines contain N strings and the total length of N strings is between 1 and 100000. The next line contains one integer Q(1≤Q≤100000) . We define a specail integer Z=0. For each query, you get two integer L, R(0=<L,R<N). Then the query interval [L,R] is [min((Z+L)%N,(Z+R)%N)+1,max((Z+L)%N,(Z+R)%N)+1]. And Z change to the answer of this query.
3 abc aba baa 3 0 2 0 1 1 1
7 6 3
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = (int)4e6+10;
const int M = (int)1e5+10;
char s[M];
int n,sz,ct,pp,ans,m,a,b,L,R;
int aa[M],mm[M],last[M],lpos[M],rpos[M];
int rt[M],ll[N],rr[N],data[N],ch[M][26];
void insert()
{
int u=0,a,len=strlen(s);
for(int i=0;i<len;i++)
{
a=s[i]-'a';
if(ch[u][a]==0)
{
ch[u][a]=++sz;
for(int j=0;j<26;j++)
ch[sz][j]=0;
}
u=ch[u][a];
aa[++ct]=u;
}
}
void build(int l,int r,int k)
{
data[k]=0;
if(l==r) return;
int mid=(l+r)/2;
ll[k]=++pp;build(l,mid,ll[k]);
rr[k]=++pp;build(mid+1,r,rr[k]);
}
void updata(int a,int b,int k,int l,int r,int x)
{
data[a]=data[b]+x;
if(l==r) return;
int mid=(l+r)/2;
if(k<=mid)
{
rr[a]=rr[b];ll[a]=++pp;
updata(ll[a],ll[b],k,l,mid,x);
}
else
{
ll[a]=ll[b];rr[a]=++pp;
updata(rr[a],rr[b],k,mid+1,r,x);
}
}
int query(int a,int b,int k,int l,int r)
{
if(a<=l&&r<=b) return data[k];
int mid=(l+r)/2,res=0;
if(mid>=a) res+=query(a,b,ll[k],l,mid);
if(mid+1<=b) res+=query(a,b,rr[k],mid+1,r);
return res;
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=0;i<26;i++)
ch[0][i]=0;
sz=ct=0;
for(int i=1;i<=n;i++)
{
scanf("%s",s);
lpos[i]=ct+1;
insert();
rpos[i]=ct;
}
for(int i=1;i<=sz;i++) mm[i]=N;
for(int i=ct;i>0;i--)
{
last[i]=mm[aa[i]];
mm[aa[i]]=i;
}
pp=0;
rt[ct+1]=++pp;build(1,ct,rt[ct+1]);
for(int i=ct;i>0;i--)
{
rt[i]=++pp;
updata(rt[i],rt[i+1],i,1,ct,1);
if(last[i]<N)
{
a=++pp;
updata(a,rt[i],last[i],1,ct,-1);
rt[i]=a;
}
}
scanf("%d",&m);ans=0;
while(m--)
{
scanf("%d%d",&a,&b);
L=min((a+ans)%n,(b+ans)%n)+1;
R=max((a+ans)%n,(b+ans)%n)+1;
ans=query(lpos[L],rpos[R],rt[lpos[L]],1,ct);
printf("%d\n",ans);
}
}
}
815



被折叠的 条评论
为什么被折叠?



