hdu5790 Prefix(Trie树+主席树)
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.
abc
aba
baa
3
0 2
0 1
1 1
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树+主席树)的更多相关文章
- 线段树简单入门 (含普通线段树, zkw线段树, 主席树)
线段树简单入门 递归版线段树 线段树的定义 线段树, 顾名思义, 就是每个节点表示一个区间. 线段树通常维护一些区间的值, 例如区间和. 比如, 上图 \([2, 5]\) 区间的和, 为以下区间的和 ...
- HDU5790 Prefix 字典树+主席树
分析:这个题和spoj的d_query是一个题,那个是求一段区间里有多少个不同的数字,这里是统计有多少个不同的前缀 用字典树进行判重,(和查询不同的数字一样)对于每个不同的前缀,只保留它最后一次出现的 ...
- 【BZOJ3439】Kpm的MC密码 trie树+主席树
Description 背景 想Kpm当年为了防止别人随便进入他的MC,给他的PC设了各种奇怪的密码和验证问题(不要问我他是怎么设的...),于是乎,他现在理所当然地忘记了密码,只能来解答那些神奇的身 ...
- HDU 5790 Prefix(Hash + 主席树)
题目链接 Prefix 题意 给定一个字符串序列,求第$l$个字符串到第$r$个字符串之间有多少个不同的前缀 强制在线 考虑$Hash$ 首先把所有前缀都$hash$出来,按顺序组成一个长度不超过 ...
- 学习笔记--函数式线段树(主席树)(动态维护第K极值(树状数组套主席树))
函数式线段树..资瓷 区间第K极值查询 似乎不过似乎划分树的效率更优于它,但是如果主席树套树状数组后,可以处理动态的第K极值.即资瓷插入删除,划分树则不同- 那么原理也比较易懂: 建造一棵线段树(权值 ...
- bzoj 3545&&3551: [ONTAK2010]Peaks &&加强版 平衡树&&并查集合并树&&主席树
3545: [ONTAK2010]Peaks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 635 Solved: 177[Submit][Stat ...
- BZOJ 4539: [Hnoi2016]树 [主席树 lca]
4539: [Hnoi2016]树 题意:不想写.复制模板树的子树,查询两点间距离. *** 终于有一道会做的题了...... 画一画发现可以把每次复制的子树看成一个大点来建一棵树,两点的lca一定在 ...
- 线段树(单标记+离散化+扫描线+双标记)+zkw线段树+权值线段树+主席树及一些例题
“队列进出图上的方向 线段树区间修改求出总量 可持久留下的迹象 我们 俯身欣赏” ----<膜你抄> 线段树很早就会写了,但一直没有总结,所以偶尔重写又会懵逼,所以还是要总结一下. ...
- UOJ#218. 【UNR #1】火车管理 线段树 主席树
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ218.html 题解 如果我们可以知道每次弹出栈之后新的栈顶是什么,那么我们就可以在一棵区间覆盖.区间求和 ...
随机推荐
- MySql创建存储过程,并使用事件定时调用
一.使用命令行创建存储过程的步骤 :参数详情参考 https://www.mysqlzh.com/ 1.模板 delimiter $$ # 设置分隔符为 '$$' ,mysql默认的语句分隔符为 ' ...
- 基于Jmeter实现Rocketmq消息发送
在互联网企业技术架构中,MQ占据了越来越重要的地位.系统解耦.异步通信.削峰填谷.数据顺序保证等场景中,到处都能看到MQ的身影. 而测试工程师在工作中,也经常需要和mq打交道,比如构造测试数据,触发某 ...
- Vue 组件内滚动条 滚到到底部
因为在vue中,某个组件内 使用scrollTop赋值 滚动条没有变化 使用scrollTo 也不行(window.scorllTo 或者dom.scrollTo) 所以可以考虑使用投机取巧的办法: ...
- 【Java基础】Eclipse 和数组
Eclipse 和数组 Eclipse 安装和使用 ... 数组的概述 数组(Array):是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理. 数组相 ...
- 了解一下IO控制器与控制方式
IO控制器 CPU无法直接控制IO设备的机械部件,因此IO设备还要有个电子部件作为CPU和IO设备机械部件之间的"中介",用于实现CPU对设备的控制. 这个电子部件就是IO控制器, ...
- paramunittest参数化测试基础
samples: import paramunittestimport unittest@paramunittest.parametrized( (10,20), (30,40), # (100,20 ...
- cut和tr命令的联合使用
cut的-d选项只能是单个字符,而对于多个连续相同字符分隔的字段,单凭cut命令是达不到想要的效果的,特别是多个连续空格分隔时. 但借助tr -s的压缩重复字符功能,可以将多个连续空格压缩为一个空格, ...
- 面试时通过volatile关键字,全面展示线程内存模型的能力
面试时,面试官经常会通过volatile关键字来考核候选人在多线程方面的能力,一旦被问题此类问题,大家可以通过如下的步骤全面这方面的能力. 1 首先通过内存模型说明volatile关键字的作用 ...
- logicaldisk本地磁盘管理
在网上搜了很多,但是基本都是一样的,差不多都是互相转载摘抄,就那么几个寥寥无几的例子,所以我冒了很大的风险,自己经过多次的测试,对这个命令有了一些新的认识!拿出来分享一下! LOGICALDISK ...
- Java异常处理场景中不同位置的返回值详细解析
Java 异常处理中的返回值在不同位置不同场景下是有一些差别的,这里需要格外注意 具体分以下两种场景: 1 finally语句块没有return语句,即当代码执行到try或者catch语句块中的ret ...