1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| #define P 998244353 int n , q; const int BLO = 150;
int son[MAXN][26] , dep[MAXN] , idx = 1 , fa[MAXN] , pos[MAXN] , S[MAXN]; void ins( char* ch , int len , int p ) { int cur = 1; per( i , len , 1 ) { if( !son[cur][ch[i] - 'a'] ) son[cur][ch[i] - 'a'] = ++ idx , dep[idx] = dep[cur] + 1 , fa[idx] = cur; cur = son[cur][ch[i] - 'a']; } pos[p] = cur; }
int s[MAXN][2] , cur; void add( int u , int w , int v ) {
while( u != 1 ) { cur -= min( s[u][0] , s[u][1] ); s[u][w] += v; cur += min( s[u][0] , s[u][1] ); u = fa[u]; } }
struct que { int l1 , r1 , l2 , r2 , idx; void in( int i ) { scanf("%d%d%d%d",&l1,&r1,&l2,&r2) , idx = i; } } Q[500006] ;
int bel[MAXN];
bool cmp( const que& a , const que& b ) { return bel[a.l1] == bel[b.l1] ? ( bel[a.l2] == bel[b.l2] ? ( bel[a.r1] == bel[b.r1] ? a.r2 < b.r2 : a.r1 < b.r1 ) : a.l2 < b.l2 ) : a.l1 < b.l1; }
char ch[MAXN]; int ans[500006]; void solve() { cin >> n >> q; rep( i , 1 , n ) { scanf("%s",ch + 1); ins( ch , strlen( ch + 1 ) , i ); S[i] = S[i - 1] + strlen( ch + 1 ); bel[i] = ( S[i] - 1 ) / BLO + 1; } rep( i , 1 , q ) Q[i].in( i ); sort( Q + 1 , Q + 1 + q , cmp ); int l = 1 , r = 0 , L = 1 , R = 0 , l1 , l2 , r1 , r2; rep( i , 1 , q ) { l1 = Q[i].l1 , l2 = Q[i].l2 , r1 = Q[i].r1 , r2 = Q[i].r2; while( l > l1 ) -- l , add( pos[l] , 0 , 1 ); while( r < r1 ) ++ r , add( pos[r] , 0 , 1 ); while( l < l1 ) add( pos[l] , 0 , -1 ) , ++ l; while( r > r1 ) add( pos[r] , 0 , -1 ) , -- r; while( L > l2 ) -- L , add( pos[L] , 1 , 1 ); while( R < r2 ) ++ R , add( pos[R] , 1 , 1 ); while( L < l2 ) add( pos[L] , 1 , -1 ) , ++ L; while( R > r2 ) add( pos[R] , 1 , -1 ) , -- R; ans[Q[i].idx] = cur; } rep( i , 1 , q ) printf("%d\n",ans[i]); }
signed main() {
solve(); }
|