Problem Description
Alice gets N strings. Now she has Q questions to ask you. For each question, she wanna know how many different prefix strings between Lth and Rth strings. It's so easy right? So solve it!
 

Input
The input contains multiple test cases.

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.
 

Output
For each question, output the answer.
 

Sample Input

3
abc
aba
baa
3
0 2
0 1
1 1
 

Sample Output

7
6

3

题意:给你n个字符串,问你第L个字符串到R个字符串中不同前缀的个数,且强制在线。

思路:这题和之前d-query这题很相似,那题问的是区间内不同数的种类。这题问的是不同前缀个数,所以我们可以先把所有的字符串插入到Trie树中,然后每次插入维护每一个节点最后被遍历到的时刻,然后用主席树维护下就行了。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ldb;
#define inf 99999999
#define pi acos(-1.0)
#define Key_value ch[ch[root][1]][0]
#define maxn 100050
#define maxnode 1000050
char s[maxn];
int n;
int ch[maxnode][28];
int val[maxnode];
int sz; #define M 1000500*30
int lson[M],rson[M],c[M],T[M];
int th; int build(int l,int r)
{
int i,j,newroot=++th,mid;
c[newroot]=0;
if(l!=r){
mid=(l+r)/2;
lson[newroot]=build(l,mid);
rson[newroot]=build(mid+1,r);
}
return newroot;
} int update(int root,int zhi,int value)
{
int i,j,newroot=++th;
int tmp=newroot;
int l=1,r=n,mid;
c[newroot]=c[root]+value;
while(l<r){
mid=(l+r)/2;
if(zhi<=mid){
r=mid;
lson[newroot]=++th;rson[newroot]=rson[root];
newroot=lson[newroot];root=lson[root];
}
else{
l=mid+1;
lson[newroot]=lson[root];rson[newroot]=++th;
newroot=rson[newroot];root=rson[root]; }
c[newroot]=c[root]+value;
}
return tmp;
} int question(int root,int pos)
{
int i,j;
int sum=0;
int l=1,r=n,mid;
while(l<r){
mid=(l+r)/2;
if(pos<=mid){
r=mid;
sum+=c[rson[root] ];
root=lson[root];
}
else{
l=mid+1;
root=rson[root];
} }
sum+=c[root];
return sum;
} void init(){
sz=0;memset(ch[0],0,sizeof(ch[0]));
memset(val,0,sizeof(val));
}
int idx(char c){
return c-'a';
} void charu(char *s,int tm){
int u=0,len=strlen(s),i,c;
T[tm]=T[tm-1];
for(i=0;i<len;i++){
c=idx(s[i]);
if(!ch[u][c]){
sz++;
memset(ch[sz],0,sizeof(ch[sz]));
val[sz]=tm;
T[tm]=update(T[tm],tm,1);
ch[u][c]=sz;
u=ch[u][c];
}
else if(ch[u][c]){
T[tm]=update(T[tm],val[ch[u][c] ],-1);
val[ch[u][c] ]=tm;
T[tm]=update(T[tm],tm,1);
u=ch[u][c];
}
}
} int main()
{
int m,i,j;
while(scanf("%d",&n)!=EOF)
{
init();
th=0;
T[0]=build(1,n);
for(i=1;i<=n;i++){
scanf("%s",s);
charu(s,i);
}
scanf("%d",&m);
int l,r,z=0,t1,t2;
for(i=1;i<=m;i++){
scanf("%d%d",&l,&r);
l=(z+l)%n+1;
r=(z+r)%n+1;
if(l>r)swap(l,r);
z=question(T[r],l);
printf("%d\n",z);
} }
return 0;
}

hdu5790 Prefix(Trie树+主席树)的更多相关文章

  1. 线段树简单入门 (含普通线段树, zkw线段树, 主席树)

    线段树简单入门 递归版线段树 线段树的定义 线段树, 顾名思义, 就是每个节点表示一个区间. 线段树通常维护一些区间的值, 例如区间和. 比如, 上图 \([2, 5]\) 区间的和, 为以下区间的和 ...

  2. HDU5790 Prefix 字典树+主席树

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

  3. 【BZOJ3439】Kpm的MC密码 trie树+主席树

    Description 背景 想Kpm当年为了防止别人随便进入他的MC,给他的PC设了各种奇怪的密码和验证问题(不要问我他是怎么设的...),于是乎,他现在理所当然地忘记了密码,只能来解答那些神奇的身 ...

  4. HDU 5790 Prefix(Hash + 主席树)

    题目链接  Prefix 题意  给定一个字符串序列,求第$l$个字符串到第$r$个字符串之间有多少个不同的前缀 强制在线 考虑$Hash$ 首先把所有前缀都$hash$出来,按顺序组成一个长度不超过 ...

  5. 学习笔记--函数式线段树(主席树)(动态维护第K极值(树状数组套主席树))

    函数式线段树..资瓷 区间第K极值查询 似乎不过似乎划分树的效率更优于它,但是如果主席树套树状数组后,可以处理动态的第K极值.即资瓷插入删除,划分树则不同- 那么原理也比较易懂: 建造一棵线段树(权值 ...

  6. bzoj 3545&&3551: [ONTAK2010]Peaks &&加强版 平衡树&&并查集合并树&&主席树

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 635  Solved: 177[Submit][Stat ...

  7. BZOJ 4539: [Hnoi2016]树 [主席树 lca]

    4539: [Hnoi2016]树 题意:不想写.复制模板树的子树,查询两点间距离. *** 终于有一道会做的题了...... 画一画发现可以把每次复制的子树看成一个大点来建一棵树,两点的lca一定在 ...

  8. 线段树(单标记+离散化+扫描线+双标记)+zkw线段树+权值线段树+主席树及一些例题

    “队列进出图上的方向 线段树区间修改求出总量 可持久留下的迹象 我们 俯身欣赏” ----<膜你抄>     线段树很早就会写了,但一直没有总结,所以偶尔重写又会懵逼,所以还是要总结一下. ...

  9. UOJ#218. 【UNR #1】火车管理 线段树 主席树

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ218.html 题解 如果我们可以知道每次弹出栈之后新的栈顶是什么,那么我们就可以在一棵区间覆盖.区间求和 ...

随机推荐

  1. 【MyBatis】MyBatis 连接池和事务控制

    MyBatis 连接池和事务控制 文章源码 MyBaits 连接池 实际开发中都会使用连接池,因为它可以减少获取连接所消耗的时间.具体可查看 MyBatis 数据源配置在 SqlMapConfig.x ...

  2. 【Spring】Spring JdbcTemplate

    Spring JdbcTemplate 文章源码 JdbcTemplate 概述 它是 Spring 框架中提供的一个对象,是对原始 Jdbc API 对象的简单封装.Spring 框架提供了很多的操 ...

  3. 剑指offer 面试题10:斐波那契数列

    题目描述 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0).n<=39 编程思想 知道斐波拉契数列的规律即可. 编程实现 class Solu ...

  4. python学习笔记 | wordcloud安装指南

    问题: 直接在命令行输入: pip install wordcloud 不出意外,直接报错,显示缺失vc*****.bat,意思是缺失vc版本,这个安装方式基本可以扔掉. 解决: http://t.c ...

  5. 【Linux】find删除365天以前的文件详细解析

    find . -name "*" -mtime +365 -exec rm -rf {} \; -mtime +365  文件被修改的时间,最后一次发生到现在365天 -atime ...

  6. 关于BAPI_GOODSMVT_CREATE中货物移动相关事务代码说明

    BAPI_GOODSMVT_CREATE参数 goodsmvt_code中的GM_CODE是为 BAPI 货物移动分配事务代码 其取值为下面对应的事务代码: 01 MB0102 MB3103 MB1A ...

  7. AWS IoT Greengrass是什么?V1和V2版本及其差异

    AWS IoT Greengrass ​ Greengrass主要是用于边缘计算或者机器学习有关,对于详细了解请阅读结尾处的官方文档,文档内容也较为丰富. 目录 AWS IoT Greengrass ...

  8. 1.5V转3.3V升压电路图和1.5V转3.3V的电源芯片

    1.5V转3.3V的电路图需要材料:PW5100芯片,2个贴片电容,1个贴片电感.即可组成一个DC-DC同步升压高效率电路图,可提供稳定的3.3V输出电压. 1.5V转3.3V的电源芯片 1.5V转3 ...

  9. Maven 知识点总结以及解决jar报冲突的几种方法

    1.常见的命令 Compile Test Package Install Deploy Clean 2.坐标的书写规范 groupId 公司或组织域名的倒序 artifactId 项目名或模块名 ve ...

  10. 异步日志 Loguru

    https://mp.weixin.qq.com/s/hy68s610B9GbL_wgwTn7nA 更优美的python日志管理库Loguru Asynchronous, Thread-safe, M ...