HDU 5790 Prefix

来源:互联网 发布:公安大数据应用现状 编辑:程序博客网 时间:2024/06/05 03:11


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(1N100000). 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(1Q100000). 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
3abcababaa30 20 11 1
 

Sample Output
763
前缀最多久10w个,可以用tire或者hash把每个串代表的前缀弄出来,然后就是询问区间内不同数字个数
这个离线的时候可以用树状数组和线段树搞定,在线的话,只要把持久化即可,用主席树就ok了
#include<set>#include<map>#include<ctime>#include<cmath>#include<stack>#include<queue>#include<bitset>#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<algorithm>#include<functional>#define rep(i,j,k) for (int i = j; i <= k; i++)#define per(i,j,k) for (int i = j; i >= k; i--)using namespace std;typedef __int64 LL;const int low(int x) { return x&-x; }const double eps = 1e-8;const int INF = 0x7FFFFFFF;const int mod = 998244353;const int N = 1e5 + 10;int n, q, sz, l, r;int f[N][26], pre[N], rt[N], L[N * 40], R[N * 40], a[N * 40], t;char s[N];int clear(int x){if (x == 0){L[t] = R[t] = a[t] = 0;return t++;}else{memset(f[sz], 0, sizeof(f[sz]));pre[sz] = 0;return sz++;}}void add(int now, int u, int v){int x = clear(0), y = rt[now], z = x;int l = 1, r = n;while (l <= r){a[x] = a[y] + v;L[x] = L[y];  R[x] = R[y];if (l == r) break;int mid = l + r >> 1;if (u <= mid){x = L[x] = clear(0);y = L[y];r = mid;}else{x = R[x] = clear(0);y = R[y];l = mid + 1;}}rt[now] = z;}int get(int x, int l, int r, int ll, int rr){if (ll <= l&&r <= rr) return a[x];int mid = l + r >> 1, res = 0;if (ll <= mid) res += get(L[x], l, mid, ll, rr);if (rr > mid) res += get(R[x], mid + 1, r, ll, rr);return res;}int main(){while (scanf("%d", &n) != EOF){t = sz = 0;clear(0); clear(1);rep(i, 1, n){scanf("%s", s);rt[i] = rt[i - 1];for (int j = 0, k = 0; s[j]; j++){if (!f[k][s[j] - 'a']) f[k][s[j] - 'a'] = clear(1);k = f[k][s[j] - 'a'];add(i, pre[k] + 1, 1);pre[k] = i;}if (i < n) add(i, i + 1, -strlen(s));}scanf("%d", &q);int Z = 0, X, Y;while (q--){scanf("%d%d", &l, &r);X = (Z + l) % n + 1;Y = (Z + r) % n + 1;if (X > Y) swap(X, Y);printf("%d\n", Z = get(rt[Y], 1, n, 1, X));}}return 0;}


0 0