Prefix

Time Limit: 2000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 858    Accepted Submission(s): 256

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
 

题目链接:HDU 5790

就是问你[L,R]中的字符串的前缀一共有多少种,那么我们可以把每一个字符串的前缀标号,然后记录这种字符串有几种前缀并更新到主席树上,每一次问[L,R]就变成询问[presum_kind[L-1]+1, presum_kind[R]]之间有几个不同的前缀标号,比如题目样例给前缀标号,就是[1,2,3][1,2,4][5,6,7]。

代码:

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(ql) (ql<<1)
#define RC(ql) ((ql<<1)+1)
#define MID(ql,qr) ((ql+qr)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 100010;
struct Trie
{
int nxt[26];
int id;
void reset()
{
fill(nxt, nxt + 26, 0);
id = 0;
}
};
struct seg
{
int lson, rson;
int cnt;
void reset()
{
lson = rson = 0;
cnt = 0;
}
};
Trie L[N];
seg T[N * 36];
int sz, tot, tid, arr[N], Tot;
int lenth[N], last[N], root[N];
char s[N]; void init()
{
sz = 1;
tot = 0;
tid = 0;
Tot = 0;
CLR(last, 0);
L[0].reset();
}
void update(int &cur, int ori, int l, int r, int pos, int flag)
{
cur = ++tot;
T[cur] = T[ori];
T[cur].cnt += flag;
if (l == r)
return ;
int mid = MID(l, r);
if (pos <= mid)
update(T[cur].lson, T[ori].lson, l, mid, pos, flag);
else
update(T[cur].rson, T[ori].rson, mid + 1, r, pos, flag);
}
int query(int S, int E, int l, int r, int ql, int qr)
{
if (ql <= l && r <= qr)
return T[E].cnt - T[S].cnt;
else
{
int ret = 0;
int mid = MID(l, r);
if (ql <= mid)
ret += query(T[S].lson, T[E].lson, l, mid, ql, qr);
if (qr > mid)
ret += query(T[S].rson, T[E].rson, mid + 1, r, ql, qr);
return ret;
}
}
int insert(int id, char s[])
{
int len = strlen(s);
int u = 0;
for (int i = 0; i < len; ++i)
{
int v = s[i] - 'a';
if (!L[u].nxt[v])
{
L[sz].reset();
L[u].nxt[v] = sz++;
}
u = L[u].nxt[v];
if (L[u].id == 0)
L[u].id = ++tid;
arr[++Tot] = L[u].id;
}
lenth[id] = Tot;
return len;
}
int main(void)
{
int n, m, i, l, r;
while (~scanf("%d%d", &n, &m))
{
init();
for (i = 0; i < n; ++i)
{
scanf("%s", s);
insert(i, s);
}
for (i = 1; i <= Tot; ++i)
{
if (!last[arr[i]])
update(root[i], root[i - 1], 1, Tot, i, 1);
else
{
int tmp;
update(tmp, root[i - 1], 1, Tot, last[arr[i]], -1);
update(root[i], tmp, 1, Tot, i, 1);
}
last[arr[i]] = i;
}
scanf("%d", &m);
int ans = 0;
while (m--)
{
int L, R;
scanf("%d%d", &L, &R);
l = min((L + ans) % n, (R + ans) % n);
r = max((L + ans) % n, (R + ans) % n);
L = l - 1 >= 0 ? lenth[l - 1] : 0;
R = lenth[r];
printf("%d\n", ans = query(root[L], root[R], 1, Tot, L + 1, R));
}
}
return 0;
}

HDU 5790 Prefix(字典树+主席树)的更多相关文章

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

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

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

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

  3. HDU5790 Prefix 字典树+主席树

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

  4. HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  5. POJ 2104&HDU 2665 Kth number(主席树入门+离散化)

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 50247   Accepted: 17101 Ca ...

  6. hdu 4417 Super Mario (主席树)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 题意: 给你段长为n的序列,有q个询问,每次询问区间[l.r]内有多少个数小于等于k 思路: 之前用 ...

  7. hdu 4348 To the moon (主席树)

    版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4348 题意: 一个长度为n的数组,4种操作 : (1)C l r d:区间[l,r]中的数都加1,同时当前的时间戳加1 . (2)Q ...

  8. HDU 4348 To the moon 主席树 在线更新

    http://acm.hdu.edu.cn/showproblem.php?pid=4348 以前做的主席树没有做过在线修改的题做一下(主席树这种东西正经用法难道不是在线修改吗),标记永久化比较方便. ...

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

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

随机推荐

  1. linux 设置自动关机和重启命令shutdown

    1.shutdown使用命令:Shutdown [选项] [时间] r 关机后立即重启 h 关机 2. 立即关机: shutdown -h now

  2. 第34-3题:LeetCode437. Path Sum III

    题目 二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数. 示例: root = [10,5,-3,3,2,null,11,3,-2,null,1], sum ...

  3. 查询删除的SAP凭证

    标准报表查询:RSSCD100 函数模块:CHANGEDOCUMENT_DISPLAY, Display Change Documents 数据表查询:CDHDR, Change document h ...

  4. 一张思维导图带你梳理HashMap相关知识

    HashMap可以说是java中最常见也是最重要的key-value存储结构类,很多程序员可能经常用,但是不一定清楚这个类背后的数据结构和相关操作原理,为了复习HashMap相关的知识,今天花了一天的 ...

  5. Spring MVC 接收前端参数的方式

    方式一: 普通方式接收 1 @RequestMapping("/index") 2 public String getUserName(String username) { 3 S ...

  6. c#字符显示转换{0:d} string.Format()

    这一篇实际和前几个月写的没什么本质上的区别.但是这篇更明确一点,学起来easy c#字符显示转换{0:d} C#:String.Format数字格式化输出 : int a = 12345678; // ...

  7. Tomcat+jdk 环境处理 java jsp代码编写web环境的容器

    Tomcat是由 Apache 软件基金会下属的 Jakarta 项目开发的一个Servlet 容器,按照 SunMicrosystems 提供的技术规范,实现了对 Servlet 和 JavaSer ...

  8. [USACO12JAN]视频游戏的连击Video Game Combos(AC自动机+DP)

    Description 贝西正在打格斗游戏.游戏里只有三个按键,分别是“A”.“B”和“C”.游戏中有 N 种连击 模式,第 i 种连击模式以字符串 Si 表示,只要贝西的按键中出现了这个字符串,就算 ...

  9. 零基础~仿qq登录界面

    html代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <t ...

  10. Python的类(一)

    类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 类变量:类变量在整个实例化的对象中是公用的.类变量定义在类中且在函数体之外. ...