题目描述:
雾
题目分析:
介绍一种很牛的东西
bitset
相减出x只需要查询(a&(a< < x)).any()即可
+法 维护一个反的bitset即可
乘法枚举因数即可
O(m*(sqrt(n)+ c / 64))
题目链接:
Ac 代码:
// luogu-judger-enable-o2
#include <cstdio>
#include <iostream>
#include <bitset>
#include <cmath>
#include <algorithm>
const int maxm=100010;
const int mx=100000;
std::bitset<maxm> a,b;
int c[maxm],n,m,num[maxm],pos[maxm];
inline void update(int w,int f)
{
c[w]+=f;
if(c[w]==1)
a[w]=b[mx-w]=1;
if(c[w]==0)
a[w]=b[mx-w]=0;
}
inline bool ask(int opt,int x)
{
if(opt==1)
{
int res=(a&(a<<x)).any();
return res!=0;
}
if(opt==2)
{
int res=(b&(a<<(mx-x))).any();
return res!=0;
}
if(opt==3)
{
for(int i=1;i<=std::sqrt(x)+1;i++)
if(!(x%i)&&c[i]&&c[x/i]) return 1;
return 0;
}
}
struct node{
int l,r,opt,x;
int id;
}q[maxm];
bool ans[maxm];
inline int read()
{
int x=0,w=1;
char ch=0;
while(ch<'0'||ch>'9')
{
if(ch=='-') w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<3)+(x<<1)+ch-'0';
ch=getchar();
}
return x*w;
}
inline bool comp(node x,node y){return pos[x.l]==pos[y.l]?x.r<y.r:x.l<y.l;}
int main()
{
n=read(),m=read();
int block_len=std::sqrt(n);
for(int i=1;i<=n;i++)
{
pos[i]=(i-1)/block_len+1;
num[i]=read();
}
for(int i=1;i<=m;i++)
q[i].opt=read(),q[i].l=read(),q[i].r=read(),q[i].x=read(),q[i].id=i;
std::sort(q+1,q+m+1,comp);
int l=1,r=0;
for(int i=1;i<=m;i++)
{
while(l>q[i].l) update(num[--l],1);
while(l<q[i].l) update(num[l++],-1);
while(r<q[i].r) update(num[++r],1);
while(r>q[i].r) update(num[r--],-1);
ans[q[i].id]=ask(q[i].opt,q[i].x);
}
for(int i=1;i<=m;i++)
puts(ans[i]?"hana":"bi");
return 0;
}