http://www.lydsy.com/JudgeOnline/problem.php?id=2555
Learned how to quickly maintain the right value Orz
(Although this is still a violent maintenance, but this is O (n) of violence 233
First we go through the parent tree when we add a new node!!!!! So that the violence is directly maintained ... I didn't even think of it.
Then, when copying a new node, don't forget to assign right to it.
And then it's a naked question.
#include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream > #include <algorithm> #include <queue> #include <set> #include <map>using namespace std; typedef long Long LL; #define REP (i, n) for (int i=0; i< (n); ++i) #define FOR1 (i,a,n) for (int i= (a); i<= (n); ++i) #define For2 (i,a,n) for (int i= (a);i< (n), ++i) #define FOR3 (i,a,n) for (int i= (a); i>= (n); i.) #define FOR4 (i,a,n) for (int i= ( a);i> (n); i) #define CC (i,a) memset (i,a,sizeof (i)) #define READ (a) a=getint () #define PRINT (a) printf ("%d", a) # Define DBG (x) cout << (#x) << "=" << (x) << endl#define error (x) (! x) puts ("error"): 0) #define RDM (x, i) for (int i=ihead[x]; i; i=e[i].next) inline const int Getint () {int r=0, k=1; Char c=g Etchar (); for (; c< ' 0 ' | | C> ' 9 '; C=getchar ()) if (c== '-') k=-1; for (; c>= ' 0 ' &&c<= ' 9 '; C=getchar ()) r=r*10+c-' 0 '; return k*r; }struct sam {static const int n=1500004;int l[n], c[n][26], F[n],Root, last, CNT, R[n];sam () {cnt=0; root=last=++cnt;} void Add (int x) {int now=last, a=++cnt; last=a;l[a]=l[now]+1;for (; now &&!c[now][x]; Now=f[now]) c[now][x]=a;if ( !now) f[a]=root;else {int q=c[now][x];if (l[q]==l[now]+1) f[a]=q;else {int b=++cnt;memcpy (c[b], c[q], sizeof c[q]); l[b]= L[now]+1;r[b]=r[q];f[b]=f[q];f[q]=f[a]=b;for (; now && c[now][x]==q; Now=f[now]) c[now][x]=b;}} while (a) ++r[a], a=f[a];} int find (char *s) {int now=root, n=strlen (s); Rep (i, N) if (! ( now=c[now][s[i]-' A '])) return 0;return R[now];}} A;void Fix (char *s, int last) {int Len=strlen (s); Rep (I, Len) {last= (last*131+i)%len;swap (S[i], s[last]);}} const int N=3000005;char s[n], W[100];int main () {int n=getint (), Len, last=0;scanf ("%s", s), Len=strlen (s); Rep (i, Len) a.a DD (s[i]-' A '); For1 (i, 1, n) {scanf ("%s%s", W, s), Len=strlen (s), fix (S, last), if (w[0]== ' Q ') {int ans=a.find (s); printf ("%d \ n ", ans); Last^=ans; }else Rep (i, Len) a.add (s[i]-' a ');} return 0;}
Description
Too lazy to write the background, give you a string init, ask you to support two operations
(1): Inserts a string after the current string
(2): How many times does the query string s appear in the current string? (as continuous substring)
You must support these operations online.
Input
The first line a number q indicates the number of operations
The second line is a string representing the initial string init
Next Q line, 2 strings per line Type,str
Type is the add word that is inserted after the string.
Type is a query that asks for a string that appears several times in the current string.
In order to represent the online operation, you need to maintain a variable mask with an initial value of 0
After reading the string str, use this procedure to decode it into a string truestr that is actually queried.
When asked, output a line answer to TRUESTR after query result
Then mask = Mask xor Result
When inserting, insert Truestr after the current string.
Both the Hint:add and query operation strings need to be decompressed
Output Sample Input 2
A
QUERY B
ADD Bbabbbbaab
Sample Output
0
HINT
40% of data string final length <= 20000, number of queries <= 1000, total length of inquiry <= 10000
100% of data string final length <= 600000, number of queries <= 10000, total length of inquiry <= 3000000
Source
CTSC Simulation by Jie Mei
"Bzoj" 2555:substring (suffix automaton)