Toad Pimple has an array of integers a1,a2,…,ana1,a2,…,an.
We say that yy is reachable from xx if x<yx<y and there exists an integer array pp such that x=p1<p2<…<pk=yx=p1<p2<…<pk=y, and api&api+1>0api&api+1>0 for all integers ii such that 1≤i<k1≤i<k.
Here && denotes the bitwise AND operation.
You are given qq pairs of indices, check reachability for each of them.
Input
The first line contains two integers nn and qq (2≤n≤3000002≤n≤300000, 1≤q≤3000001≤q≤300000) — the number of integers in the array and the number of queries you need to answer.
The second line contains nn space-separated integers a1,a2,…,ana1,a2,…,an (0≤ai≤3000000≤ai≤300000) — the given array.
The next qq lines contain two integers each. The ii-th of them contains two space-separated integers xixi and yiyi (1≤xi<yi≤n1≤xi<yi≤n). You need to check if yiyi is reachable from xixi.
Output
Output qq lines. In the ii-th of them print "Shi" if yiyi is reachable from xixi, otherwise, print "Fou".
Example
input
Copy
5 3 1 3 0 2 1 1 3 2 4 1 4
output
Copy
Fou Shi Shi
Note
In the first example, a3=0a3=0. You can't reach it, because AND with it is always zero. a2&a4>0a2&a4>0, so 44 is reachable from 22, and to go from 11 to 44 you can use p=[1,2,4]p=[1,2,4].
题意:给你一个序列,q次询问,每次询问给出l和r,问你是否可以从l到r中选出一个序列,选出的序列值对应原序列的下标,使得相邻的两个值AND大于0
题解:要使AND不为0,就会在相同位置都出现1,找出当前值的二进制为1时,右边最近的二进制同为1的值,如果这个值的下标是小于等于右端点,则代表是可行方案,否则不是,由于是一个序列所以如果两个值AND不为0,那么左边的位置就会被右边可以到的位置更新,记录当前位为1时,最小的下标,如果跑到当前位置的数的二进制同为1就可以将其调出更新,在把当前位为1的最小位置更新掉;
AC代码:
#include<stdio.h>
#include<vector>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue>
#define ll long long
using namespace std;
const int maxn=3e5+5;
//const ll inf=9223372036854775800;
//const int inf=1e9;
//const int mod=1e9+7;
int dp[maxn][21],xi[maxn];
int num[21];
void get(int k){
for(int a=0;a<=20;a++){
if((xi[k]>>a)&1){
dp[k][a]=k;
if(num[a]){
for(int b=0;b<=20;b++)
dp[k][b]=min(dp[k][b],dp[num[a]][b]);
}
num[a]=k;
}
}
}
int main( ){
int n,m;
memset(num,0,sizeof(num));
scanf("%d %d",&n,&m);
for(int a=1;a<=n;a++){
scanf("%d",&xi[a]);
for(int b=0;b<=20;b++)
dp[a][b]=maxn;
}
for(int a=n;a>=1;a--)
get(a);
int l,r;
while(m--){
scanf("%d %d",&l,&r);
bool judge=false;
for(int a=0;a<=20;a++){
if(((xi[r]>>a)&1)&&dp[l][a]<=r){
judge=true;
break;
}
}
if(!judge)
printf("Fou\n");
else
printf("Shi\n");
}
}