Title Link: Luo Gu
Title Description: give the number of $n $$a_i $, if $I < J $and $a_i & a_j > 0 $, then $I $to $J $are connected with a directed side, $q $times, and ask if it can reach $r $from $l $.
Data range: $n,q\leq 3*10^5$
A wonderful thought problem. (binary is used for the following)
Maintain two arrays, $g {i, j} $indicates the subscript with the largest subscript and the first $j $bit of the number with subscript less than $i $. $f {i, j} $indicates that the subscript of a number whose subscript is less than $i $is the largest, the $j $bit is 1, and the subscript of $i $can be reached.
Needless to say, the preprocessing of $g {i, J} $can enumerate a bit of $k $, which means that $a {i $can be reached from $g {i, K} $through the $k $, and the f value of $i $can be directly deduced by using the f value of $g {i, K} $.
When asking, enumerate a bit of $i $, which means that $r $can arrive from $f {r, i} $, while when the $i $bit of $a {L $is 1 and $f {r, i} \ GEQ L $can arrive at $f {r, i} $, so $l $can arrive at $r $. If not for each bit, output fou.
Time complexity $O(n\log^2n+q\log n)$
CF1168C1 #include<bits/stdc++.h> 2 #define Rint register int 3 using namespace std; 4 const int N = 300001; 5 int n, m, f[N][19], g[N][19]; 6 bool a[N][19]; 7 int main(){ 8 scanf("%d%d", &n, &m); 9 for(Rint i = 1;i <= n;i ++){ 10 int x; 11 scanf("%d", &x); 12 for(Rint j = 0;j < 19;j ++) 13 if(x & (1 << j)) a[i][j] = 1; 14 } 15 for(Rint i = 1;i <= n;i ++) 16 for(Rint j = 0;j < 19;j ++) 17 if(a[i - 1][j]) g[i][j] = i - 1; 18 else g[i][j] = g[i - 1][j]; 19 for(Rint i = 1;i <= n;i ++) 20 for(Rint j = 0;j < 19;j ++) 21 for(Rint k = 0;k < 19;k ++) 22 if(a[i][k]){ 23 int x = g[i][k]; 24 f[i][j] = max(f[i][j], f[x][j]); 25 if(a[x][j]) f[i][j] = max(f[i][j], x); 26 } 27 while(m --){ 28 int l, r; 29 bool ans = false; 30 scanf("%d%d", &l, &r); 31 for(Rint i = 0;i < 19 && !ans;i ++) 32 if(a[l][i] && f[r][i] >= l) ans = true; 33 puts(ans ? "Shi" : "Fou"); 34 } 35 }