哇。
难死了。
题解说得好。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include <bits/stdc++.h> 2 #define rep(n) for(int i=1;i<=n;i++) 3 using namespace std; 4 typedef long long ll; 5 const int N = 3e5+5; 6 int n,q,a[N],dp[N][20],las[20]; 7 // ?????,? is the smallest ?>?, such that ?? contains bit ?. 8 //dp[i][j]从i位置及其之后的位置中,二进制位的第j位为1,并且可达的最靠前的位置 9 int main(){ 10 ios::sync_with_stdio(false); 11 cin>>n>>q; 12 rep(n)cin>>a[i]; 13 for(int i=0;i<20;i++){ 14 las[i]=n+1; 15 dp[n+1][i]=n+1; 16 } 17 for(int i=n;i>=1;i--){ 18 for(int j=0;j<20;j++) 19 dp[i][j]=n+1; 20 for(int j=0;j<20;j++){ 21 if(a[i]&(1<<j)){ 22 for(int k=0;k<20;k++){ 23 dp[i][k]=min(dp[i][k],dp[las[j]][k]); 24 } 25 las[j]=i; 26 dp[i][j]=i; 27 } 28 } 29 } 30 int x,y; 31 while (q--){ 32 cin>>x>>y; 33 bool f=0; 34 for(int i=0;i<20;i++){ 35 if(a[y]&(1<<i)&&dp[x][i]<=y){ 36 f=1; 37 break; 38 } 39 } 40 if(f)cout<<"Shi"<<endl; 41 else cout<<"Fou"<<endl; 42 } 43 }