都快忘了在这类题的经典做法了……

将字符串一个个的插入字典树,在字典树维护好有该前缀串s的最大编号字符串j,我们记作j控制了前缀串s

对于当前的第i个字符串,维护此时有当前每个字符串控制了多少个前缀串,用一个线段树维护。

由于询问是在线的,所以用主席树来维护。于是对一个询问(l,r),在第r个线段树求一下区间(l,r)的和即为答案。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std;
struct node{int l,r,s;} tree[*];
int go[][],h[],be[];
char s[];
int m,t,n,q; int build(int l,int r)
{
++t; tree[t].l=tree[t].r=tree[t].s=;
if (l==r) return t;
else {
int cur=t,m=(l+r)>>;
tree[cur].l=build(l,m);
tree[cur].r=build(m+,r);
return cur;
}
} int work(int l,int r,int last,int x,int w)
{
++t; tree[t]=tree[last];
if (l==r) {tree[t].s+=w; return t;}
else {
int cur=t,m=(l+r)>>;
if (x<=m) tree[cur].l=work(l,m,tree[last].l,x,w);
else tree[cur].r=work(m+,r,tree[last].r,x,w);
tree[cur].s=tree[tree[cur].l].s+tree[tree[cur].r].s;
return cur;
}
} int ask(int l,int r,int p,int x,int y)
{
if (x<=l&&y>=r) return tree[p].s;
else {
int m=(l+r)>>,s=;
if (x<=m) s+=ask(l,m,tree[p].l,x,y);
if (y>m) s+=ask(m+,r,tree[p].r,x,y);
return s;
}
} int main()
{
while (scanf("%d",&n)!=EOF)
{
t=m=;
h[]=build(,n);
memset(go[],,sizeof(go[]));
for (int i=; i<=n; i++)
{
scanf("%s",s+);
int k=,l=strlen(s+);
h[i]=h[i-];
for (int j=; j<=l; j++)
{
int c=s[j]-'a';
if (!go[k][c]) {go[k][c]=++m; memset(go[m],,sizeof(go[m])); be[m]=;}
k=go[k][c];
if (be[k]) h[i]=work(,n,h[i],be[k],-);
be[k]=i;
}
h[i]=work(,n,h[i],i,l);
}
scanf("%d",&q);
int z=;
for (int i=; i<=q; i++)
{
int l,r;
scanf("%d%d",&l,&r);
l=(z+l)%n+; r=(z+r)%n+;
if (l>r) swap(l,r);
z=ask(,n,h[r],l,r);
printf("%d\n",z);
}
}
return ;
}

hdu5790的更多相关文章

  1. HDU5790 Prefix 字典树+主席树

    分析:这个题和spoj的d_query是一个题,那个是求一段区间里有多少个不同的数字,这里是统计有多少个不同的前缀 用字典树进行判重,(和查询不同的数字一样)对于每个不同的前缀,只保留它最后一次出现的 ...

  2. hdu5790 Prefix(Trie树+主席树)

    Problem Description Alice gets N strings. Now she has Q questions to ask you. For each question, she ...

随机推荐

  1. Java循环控制语句-switch

    Java循环控制语句之一switch 不同于其他循环控制语句的特性: switch的英文解释为开关,正如它的解释一样,switch循环的特点就像开关一样,跳到哪一个条件即会出现某一种结果. 写法: s ...

  2. 先查出已知的 然后将未知的当做 having里面的条件

    先查出已知的 然后将未知的当做 having里面的条件

  3. COGS 497——奶牛派对

    奶牛派对 我们发现每头牛需要走的路程即为它到x的最短路+x到它的最短路. 转化: 于是这道题变成了一道典型的单源最短路问题,只需求出每个点到x的最短路dl,以及从x到此点的最短路d2,然后去找max( ...

  4. JAVA 异常处理的认知学习过程

    没有异常处理 学生时代,我编写的java代码中,很少会有try catch.最主要的原因如下: 应用的规模很小 没有不确定因素 代码可控性高 如果规模小,往往就没有复杂的逻辑链路,整个软件的分层也很浅 ...

  5. 【题解】SDOI2011消耗战

    虚树模板题~洛谷P2495 第一次写虚树,感觉好厉害呀~首先,这道题目的树形dp是非常显然的,要控制一个点&其子树所有点,要么在子树内部割边,要么直接切点该点与父亲的连边.所以dp[u]表示控 ...

  6. sublime text : The emmet plugin doesn't work when tab key was pressed

    Today, I switched my sublime text to version 3. And then I found that  the emmet plugin doesn't work ...

  7. CF840C On the Bench 解题报告

    CF840C On the Bench 题意翻译 给定\(n\) \((1≤n≤300)\) 个数,求问有多少种排列方案使得任意两个相邻的数之积都不是完全平方数.由于方案数可能很大,输出方案数 \(m ...

  8. SqlServer中临时表的应用

    一.变通处理WHERE后面IN的参数过多 WHERE后面的条IN操作符里的参数比较小时,可以直接使用IN(1,2,3)这样处理,当个数不确定(可能超过1000)时,应该考虑使用临时表关联查询: SEL ...

  9. SICAU-OJ: 第k小

    第k小 题意: 给出一个长度不超过5000的字符串,然后让你找出第K小的字串(1<=K<=5).重复的串大小相等. 题解: 这里我们知道某些串的前缀是肯定小于等于其本身的. 那么长度为5的 ...

  10. JAVA中string.replace()和string.replaceAll()的区别及用法

    乍一看,字面上理解好像replace只替换第一个出现的字符(受javascript的影响),replaceall替换所有的字符,其实大不然,只是替换的用途不一样.    public String r ...