Test instructions: Given multiple string s1...sn, each string si corresponds to the happy value Hi, for a string T, if it is in the string Si,sj,sk. The happy value for the string T is hi * HJ * HK * ..., asking for an m, the output length <=m the happy value of the random string is expected.
First, a violent practice, traversing all the substrings of s1...sn, for a substring T, to calculate its contribution to ans (len (t)), do not repeat the sum of all the sub-string contributions, and finally take the prefix and can.
Looking back at each of the Sam's states (points), it represents multiple strings, which have the same set of end positions, and if they are sorted by length, they increment in length and each string is the suffix of the string with the largest length of the string, such as BBC,BBCD,BBCDC, which is well understood, Since the string of the maximum length ends in a position k, all its suffixes will also appear in K, why not from length 1 to length Max, because a string of small length may appear elsewhere, meaning that a string's occurrence position set size is always less than or equal to the occurrence of its suffix.
Back to this question, and then see the broad-based Sam approach, first of all, to establish a generalized Sam how to do, at this time each substring in the SAM, in a single string of Sam, each point represents a string has the same end position set, that in the generalized Sam also has the same end position set, and these strings appear in which string is the same So the happy value of these strings is the same, and the happy value of that point is the multiplicative all H value of the string set.
So how to build a broad Sam? When the SAM is established on a string Si, it starts from the initial state, and when the character C = s[i][j] is added, if it is found that the current state St already has an edge of C pointing to the next State V, and the maximum length of the string represented by V = the current matched string length, that State v can represent the current string s[i][0]...s[i][j] , or create a new node (not proof).
How does the generalized Sam maintain the happy value? Each string runs again, the points encountered are maintained on the weight, and to go along the fail side to update, each point only updated once.
The next step is to iterate through all the points of the statistical answer, because a point represents the length of multiple strings is continuous, so the interval is covered.
#include <iostream> #include <cmath> #include <cstring> #include <queue> #include <vector > #include <cstdio> #include <algorithm> #include <map> #include <set> #define REP (i,e) for ( int i=0;i< (e); i++) #define REP1 (I,e) for (int. i=1;i<= (e); i++) #define REPX (i,x,e) for (int i= (x); i<= (e); i++) # Define PII pair<int,int> #define X first#define Y second#define PB push_back#define MP make_pair#define mset (var,val ) memset (Var,val,sizeof (VAR)) #define SCD (a) scanf ("%d", &a) #define SCDD (A, b) scanf ("%d%d", &a,&b) #define SCDDD (a,b,c) scanf ("%d%d%d", &a,&b,&c) #define IOS Ios::sync_with_stdio (false); Cin.tie (0); Cout.tie (0) Using namespace Std;typedef long long ll;template <class t>void test (T a) {Cout<<a<<endl;} Template <class t,class t2>void test (T a,t2 b) {cout<<a<< "" <<B<<ENDL; Template <class t,class t2,class t3>void Test (T a,t2 b,t3 c) {cout<<a<< "" <<b<< "" <<c<<endl;} const int N = 1e6+10;const int inf = 0x3f3f3f3f;const ll inf = 0x3f3f3f3f3f3f3f3f;const int mod = 1e9+7;int idx;int maxlen [N], minlen[n], trans[n][26], slink[n];int new_state (int _maxlen, int _minlen, int* _trans, int _slink) {Maxlen[idx] = _maxlen; MINLEN[IDX] = _minlen; for (int i = 0; i < i++) {if (_trans = = NULL) Trans[idx][i] = 1; else trans[idx][i] = _trans[i]; } Slink[idx] = _slink; return idx++;} int val[n];int Add_char (char ch, int u) {int c = ch-' a '; int z = new_state (Maxlen[u] + 1,-1, NULL,-1); while (U! =-1 && trans[u][c] = = 1) {Trans[u][c] = Z; U = slink[u]; } if (U = =-1) {minlen[z] = 1; Slink[z] = 0; return z; } int x = Trans[u][c]; if (Maxlen[u] + 1 = = Maxlen[x]) {minlen[z] = maxlen[x] + 1; SLINK[Z] = x; return z; } int y = New_state (Maxlen[u] + 1,-1, trans[x], slink[x]); Minlen[z] = MinlEN[X] = Maxlen[y] + 1; SLINK[Z] = slink[x] = y; while (U! =-1 && trans[u][c] = = x) {Trans[u][c] = y; U = slink[u]; } Minlen[y] = Maxlen[slink[y]] + 1; return z;} String S[n];int h[n];int wlk[n];ll Qpow (ll A,ll b) {ll ret = 1; while (b) {if (b&1) Ret=ret*a%mod; b>>=1; A=a*a%mod; } return ret;} ll INV (ll a) {return Qpow (a,mod-2);} int ans[n];int vis[n];void work () {int n;cin>>n; int mxlen = 0; Rep (i,n) {cin>>s[i]; Mxlen = Max (Mxlen, (int) s[i].size ()); } new_state (0,0,null,-1); Rep (i,n) {cin>>h[i]; int st=0; Rep (J,s[i].size ()) {int NX = trans[st][s[i][j]-' a ']; if (NX = =-1 | | maxlen[nx]! = j+1) {//Jianguangyi Sam, two cases St=add_char (S[i][j], ST); }else{st = NX; }}} Rep (i,n) {int st=0; Rep (J,s[i].size ()) {st = trans[st][s[i][j]-' a ']; int u = st; while (u!=-1) {//Traverse all and the string-related points if (vis[u]==i+1) break;//memset vis vis[u]=i+1; if (!val[u]) val[u]=h[i]; else Val[u]=1ll*val[u]*h[i]%mod; U=slink[u]; }}} rep1 (I,idx-1) {(Wlk[minlen[i]] + val[i])%=mod; (wlk[maxlen[i]+1]-= val[i])%=mod;//interval overwrite} int now = 0; int sum = 0; int div = 0; int pw = 1; REP1 (I,mxlen) {pw=pw*26ll%mod; (DIV+=PW)%=mod; (now + = wlk[i])%=mod; (Sum+=now)%=mod; Ans[i] = 1ll*sum*inv (div)%mod; } int m;cin>>m; Rep (i,m) {int x;cin>>x; if (x>mxlen) x = mxlen;//Remember the special sentence test ((ans[x]+mod)%mod); }}int Main () {#ifdef local freopen ("In.txt", "R", stdin); #endif//local IOS; Work ();}
HDU6405 make ZYB Happy generalized Sam