【题目链接】
https://www.lydsy.com/JudgeOnline/problem.php?id=4810
【题解】
首先可以离线下来使用莫队,这样就知道了每个询问区间中每个数是否出现,将其压为一个bitset,记为 f f 。
考虑如何询问:
对于操作1:可行的条件是 f f ^ f<<x f << x 不全为 0 0 。
对于操作2:记 g g 表示 f f 翻转后的结果(第i位于第(最高位-i)位替换),那么可行的条件是 f f ^ g<<(最高位−x) g << ( 最 高 位 − x ) 不全为0。
对于操作3:直接枚举 x x 的因数。
时间复杂度 O(N∗N−−√+N2/64) O ( N ∗ N + N 2 / 64 )
【代码】
/* - - - - - - - - - - - - - - -
User : VanishD
problem : [bzoj4810]
Points : bitset
- - - - - - - - - - - - - - - */
# include
# define ll long long
# define inf 0x3f3f3f3f
# define N 100010
using namespace std;
int read(){
int tmp = 0, fh = 1; char ch = getchar();
while (ch < '0' || ch > '9'){ if (ch == '-') fh = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9'){ tmp = tmp * 10 + ch - '0'; ch = getchar(); }
return tmp * fh;
}
struct Node{
int opt, l, r, x, id;
}q[N];
bool ans[N];
int use[N];
int n, m, size, num[N];
bitset hav0, hav1;
bool cmp(Node x, Node y){
return x.l / size < y.l / size || (x.l / size == y.l / size && x.r < y.r);
}
inline void ins(int x){hav0.set(x); hav1.set(N - x);}
inline void del(int x){hav0.reset(x); hav1.reset(N - x);}
int main(){
// freopen("bzoj4810.in", "r", stdin);
// freopen("bzoj4810.out", "w", stdout);
n = read(), m = read();
for (int i = 1; i <= n; i++) num[i] = read();
size = (int)pow(n, 0.5);
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;
}
sort(q + 1, q + m + 1, cmp);
int nowl = 1, nowr = 0;
for (int i = 1; i <= m; i++){
for (int j = nowr + 1; j <= q[i].r; j++){
use[num[j]]++;
if (use[num[j]] == 1) ins(num[j]);
}
for (int j = nowl - 1; j >= q[i].l; j--){
use[num[j]]++;
if (use[num[j]] == 1) ins(num[j]);
}
for (int j = nowl; j < q[i].l; j++){
use[num[j]]--;
if (use[num[j]] == 0) del(num[j]);
}
for (int j = nowr; j > q[i].r; j--){
use[num[j]]--;
if (use[num[j]] == 0) del(num[j]);
}
nowl = q[i].l; nowr = q[i].r;
if (q[i].opt == 1)
if ((hav0 & (hav0 << q[i].x)).any() != 0)
ans[q[i].id] = true;
if (q[i].opt == 2)
if ((hav0 & (hav1 >> (N - q[i].x))).any() != 0)
ans[q[i].id] = true;
if (q[i].opt == 3){
bool flag = false;
for (int j = 1; j * j <= q[i].x; j++){
if (q[i].x % j != 0) continue;
if (use[j] != 0 && use[q[i].x / j] != 0){
flag = true;
break;
}
}
if (flag == true) ans[q[i].id] = true;
}
}
for (int i = 1; i <= m; i++)
puts((ans[i] == true) ? "yuno" : "yumi");
return 0;
}