仅供参考
```cpp
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int pos[N],a[N],n,m,p,cnt[N];
bool ans[N];
struct queries {
int op,l,r,x,id;
queries() {
op=l=r=x=id=0;
}
queries(int O,int L,int R,int X,int I) {
op=O,l=L,r=R,x=X,id=I;
}
bool operator < (queries x) const {
if(pos[l]==pos[x.l]) return r<x.r;
return l<x.l;
}
} que[N];
bitset<N> pre,suf;
void add(int x) {
++cnt[a[x]];
if(cnt[a[x]] == 1){
pre.set(a[x]);
suf.set(n-a[x]);
}
}
void sub(int x) {
--cnt[a[x]];
if(!cnt[a[x]]) {
pre[a[x]]=0;
suf[n-a[x]]=0;
}
}
int main() {
scanf("%d %d",&n,&m);
p=sqrt(n);
for(int i=1; i<=n; ++i) scanf("%d",&a[i]),pos[i]=(i-1)/p+1;
for(int i=1; i<=m; ++i) {
int o,l,r,x,id=i;
scanf("%d %d %d %d",&o,&l,&r,&x);
que[i]=queries(o,l,r,x,id);
}
sort(que+1,que+1+m);
for(int i=1,l=1,r=0; i<=m; ++i) {
while(l>que[i].l) add(--l);
while(l<que[i].l) sub(l++);
while(r<que[i].r) add(++r);
while(r>que[i].r) sub(r--);
if(que[i].op==1 && (pre&(pre<<que[i].x)).any()) ans[que[i].id]=true;
if(que[i].op==2 && (pre&(suf>>(n-que[i].x))).any()) ans[que[i].id]=true;
if(que[i].op==3) {
for(int j=1; j*j<=que[i].x; ++j) {
if(que[i].x%j==0 && pre[j] && pre[que[i].x/j]) {
ans[que[i].id]=true;
break;
}
}
}
}
for(int i=1; i<=m; ++i) puts(ans[i]?"hana":"bi");
return 0;
}
by AlexSong @ 2023-08-18 11:29:34
@[AlexSong](/user/1004299) 能不能给点帮助
实在看不懂
by lonely_cyx @ 2023-08-18 11:31:37
我也解释不了,但是能看懂
by AlexSong @ 2023-08-18 11:40:22
@[lonely_cyx](/user/276588) 第三行 `N` 开太大了,数组后面调用 `add` 和 `cel` 函数时越界了。
by Z_301 @ 2023-08-18 22:05:53