Topic Link
because each number is \ (10 ^ 5 \) or less, consider the direct use of \ (bitset \) maintenance.
\ (the X-ab = \) , in fact, to see if there \ (p \) and \ (p + x \) exist, directly \ (bitset \) shift bit and just fine.
\ (A + B = X \) , it might do this directly, so consider conversion.
\ [a- (Nb) = a
+ bN = xN \] where \ (N \) is a constant, so that \ (F (X) = Nx of \) , there are
\ [f (b) -f ( x) = a \]
so then open \ (the bitset \) maintenance \ (F (X) \) , then it is obviously the.
\ (the X-A * b = \) , this obviously can not use \ (bitset \) do, but \ (x \) the number of factors is \ (\ sqrt x \) level, so a direct enumeration of violence factor on the line a.
To prevent negative, the above \ (N \) range in question to take the upper limit \ (10 ^ 5 \)
The last team put Mo template.
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <bitset>
#include <cmath>
#include <iostream>
using namespace std;
const int MAXN = 100010;
bitset <MAXN> p1, p2;
int n, m, a[MAXN];
inline int read(){
int s = 0;
char ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); }
return s;
}
int Q, v[MAXN], ans[MAXN];
struct ask{
int type, l, r, c, id;
int operator < (const ask A) const{
return l / Q == A.l / Q ? r < A.r : l < A.l;
}
}q[MAXN];
void add(int x){
++v[a[x]];
p1[a[x]] = p2[100000 - a[x]] = 1;
}
void del(int x){
if(!--v[a[x]])
p1[a[x]] = p2[100000 - a[x]] = 0;
}
int main(){
n = read(); m = read(); Q = sqrt(n);
for(int i = 1; i <= n; ++i)
a[i] = read();
for(int i = 1; i <= m; ++i)
scanf("%d%d%d%d", &q[i].type, &q[i].l, &q[i].r, &q[i].c), q[i].id = i;
sort(q + 1, q + m + 1);
int l = 1, r = 0;
for(int i = 1; i <= m; ++i){
while(r < q[i].r) add(++r);
while(l > q[i].l) add(--l);
while(r > q[i].r) del(r--);
while(l < q[i].l) del(l++);
if(q[i].type == 1){
ans[q[i].id] = (p1 & (p1 >> q[i].c)).any();
}else if(q[i].type == 2){
ans[q[i].id] = (p1 & (p2 >> (100000 - q[i].c))).any();
}else{
if(!q[i].c) ans[q[i].id] = v[0];
int sqr = sqrt(q[i].c);
for(int j = 1; j <= sqr; ++j)
if(q[i].c % j == 0)
if(v[j] && v[q[i].c / j]){
ans[q[i].id] = 1;
break;
}
}
}
for(int i = 1; i <= m; ++i)
printf("%s\n", ans[i] ? "hana" : "bi");
return 0;
}