We first consider how to compare the two or two string
We can use the line tree tree to maintain the beh value on the online section tree according to the nature of the dictation
Considering that each thread tree is only a modified node on the basis of a previous one, it obviously think of the chairman tree
In addition, how to pushup, we consider such a string ABCDEFG
Assume that the left son of the current node is ABC right son is DEFG
Since our hash value uses UNSIGNED Long Long naturally overflows Dafa, that is to say, the hash value of ABC is A(base^1)+b(base^2)+c(base^3), and the hash value of Defg is D(base^1)+…
So just take a base^3 for CEFG
code is also very easy to write
#include <bits/stdc ++. H>
#Define n 100005
#Define M 100005
#Define Ull unsigned long long
const int base = 31;
using namespace std;
int n, m, tot, len [n], sum [n], p [n], lc [n], rc [n], rt [n];
ull pw [m];
char s [n];
void Build (int & new, int L, int R)
{{
Now = ++ TOT; Len [now] = r-l+1;
if (l == r)
{{
sum [now] = s [l];
Return;
}
int m = (l+r) >> 1;
Build (LC [now], L, M);
Build (rc [now], m+1, r);
Sum [now] = Sum [lc [now]]+Sum [rc [now]]*pw [lc [now]]];
}
Inline void copy (int & x, int y)
{{
x = ++ tot;
lc [x] = lc [y]; rc [x] = rc [y]; len [x] = len [y]; sum [x] = sum [y];
}
Inline void insert (int x, int & y, int l, int r, int p, int v)
{{
Copy (y, x);
if (l == r) // Copy x to Y
{{
Sum [y] = v;
Return;
}
int m = (l+r) >> 1;
if (p <= m) insert (lc [x], lc [y], l, m, p, v);
Else INSERT (RC [X], RC [Y], M+1, R, P, V);
SUM [y] = Sum [lc [y]]+Sum [rc [y]]*pw [lc [lc [y]]];
}
Inline int CMP (int x, int y, int L, int R)
{{
if (l == r)
{{
if (Sum [x] <sum [y]) Return -1;
else Return 1;
}
int m = (l+r) >> 1;
if (SUM [LC [x]]! = Sum [LC [y [y]]) Return CMP (LC [x], LC [y], m);
Else Return CMP (RC [x], RC [y], m+1, r);
}
Inline Bool Comp (CONST INT Int & A, Const Int & B)
{{
if (SUM [RT [A]] == Sum [rt [b]]) Return a <b;
Return CMP (RT [A], RT [B], 1, M) <0;
}
int Main ()
{{
cin >> n >> m;
scanf ("%s", s+1);
pw [0] = 1;
for (int i = 1; i <= m; i ++) pw [i] = pw [i-1]*base;
Build (RT [1], 1, M);
for (int i = 2; i <= n; i ++)
{{
int WHO, POS;
cin >> who >> pos;
scanf ("%s", s+1);
Insert (RT [WHO], RT [i], 1, M, POS, S [1]); //
}
For (int i = 1; i <= n; i ++) p [i] = i;
sort (P+1, P+N+1, COMP);
for (int i = 1; i <= n; i ++) Cout << p [i] << "" "" "" "" "" "
Return 0;
}