\(\text{bitset}\)神题啊。
首先你得想到这题得用\(\text{bitset}\)来做。
我们先设一个\(\text{bitset,zhe}\)其第\(i\)位表示\(i\)这个数字有没有出现。
我们再设一个\(\text{bitset,rev}\)其第\(i\)位表示\(n-i\)是否出现。
接着我们看询问:
对于加法:我们只需要将\(\text{zhe}\)与\(\text{zhe<<x}\)做一下\(and\)运算就好了。
对于减法:
我们先推一下式子:
\(z+y=x\)
\(n-(n-y)+z=x\)
\(z-(n-y)=x-n\)
这样就和加法形式一样了
乘法:乘法没什么技巧,直接枚举因数
对于询问的话其实我们用一个莫队滚一下就好了
#include <bits/stdc++.h>
#define il inline
#define gc getchar
#define isd(c) (c >= ‘0‘ && c <= ‘9‘)
const int MAXN = 1e5 + 10;
const int MAXM = MAXN;
using namespace std;
il int read() {
int res = 0;char c;bool sign = 0;
for(c = gc();!isd(c);c = gc()) sign |= c == ‘-‘;
for(;isd(c);c = gc()) res = (res << 1) + (res << 3) + (c ^ 48);
return sign ? -res : res;
}
int a[MAXN],bel[MAXN],cnt[MAXN];bool ans_arr[MAXM];
int n,m,i,j,k;
struct Questions {
int opt,l,r,x,id;
Questions() {opt = l = r = x = id = 0;}
Questions(int _opt,int _l,int _r,int _x,int _id) {
opt = _opt;l = _l;r = _r;x = _x;id = _id;
}
}Query[MAXM];
bitset<MAXN>zhe,rev;
il bool cmp1(Questions a,Questions b) {
if(bel[a.l] != bel[b.l]) return bel[a.l] < bel[b.l];
else return a.r < b.r;
}
il void add(int x) {
int tmp = a[x];
cnt[tmp]++;cnt[tmp] == 1 ? zhe[tmp] = 1,rev[n - tmp] = 1 : NULL;
}
il void del(int x) {
int tmp = a[x];
cnt[tmp]--;!cnt[tmp] ? zhe[tmp] = 0,rev[n - tmp] = 0 : NULL;
}
int main() {
n = read();m = read();
for(int i = 1;i <= n;i++) a[i] = read();const int bls = (int)(sqrt(n));
for(int i = 1;i <= m;i++) {
int opt = read(),l = read(),r = read(),x = read();
Query[i] = Questions(opt,l,r,x,i);
bel[i] = (i - 1) / bls + 1;
}
sort(Query + 1,Query + m + 1,cmp1);
int l = 1,r = 0;
for(int _i = 1;_i <= m;_i++) {
while(l > Query[_i].l) add(--l);
while(r < Query[_i].r) add(++r);
while(l < Query[_i].l) del(l++);
while(r > Query[_i].r) del(r--);
int x = Query[_i].x;
switch(Query[_i].opt) {
case 1: {
if((zhe & (zhe << x)).any()) ans_arr[Query[_i].id] = 1;
break;
}
case 2: {
if((zhe & (rev >> n - x)).any()) ans_arr[Query[_i].id] = 1;
break;
}
case 3: {
for(int i = 1;i <= (int)(sqrt(x));i++) {
if(x % i == 0) {
if(zhe[i] && zhe[x / i]) {
ans_arr[Query[_i].id] = 1;
break;
}
}
}
break;
}
}
}
for(int i = 1;i <= m;i++) {
ans_arr[i] ? puts("hana") : puts("bi");
}
return 0;
}
原文:https://www.cnblogs.com/Sai0511/p/10360579.html