LuoguP3674 小清新人渣的本愿

题目地址

题目链接

题解

这种lxl的题还是没修改操作的题基本就是莫队

分开考虑每个询问

1.减法

\(a-b=x⇒a=b+x\)

用一个\(bitset\),第\(i\)位表示有没有\(i\)这个数

那么查询其实就等价于查询bit&(bit>>x)之后里面有没有1

\(a+b=x\)

2.加法

\(a+b=x\)

\(p=n-b\)

\(a-p=a-n+b=x-n\)

维护一下另外一个\(bitset\),里面存的是\(n-i\)有没有出现过

查询直接查bit1&(bit2>>(n-x))里面有没有1就好

3.乘法

乘法不好维护

但是直接枚举因数也是可以的,在第一个bitset里面看成对的因数有没有出现过就好

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <bitset>
using namespace std;

inline int read() {
    int x = 0, f = 1; char c = getchar();
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
    return x * f;
}

#define N 100010

bitset<N>s1;
bitset<N>s2;
int cnt[N];
int n, m, a[N];
int ans[N], block;
struct ques {
    int opt, l, r, x, id;
} q[N];

bool cmp(ques a, ques b) {
    if(a.l / block == b.l / block) return a.r < b.r;
    else return a.l < b.l;
}

void add(int x) {
    x = a[x];
    cnt[x]++;
    if(cnt[x] == 1) s1[x] = s2[n - x] = true;
}

void dele(int x) {
    x = a[x];
    cnt[x]--;
    if(!cnt[x]) s1[x] = s2[n - x] = false;
}

int main() {
    n = read(); m = read();
    for(int i = 1; i <= n; i ++) a[i] = read();
    block = n / sqrt(m);
    for(int i = 1; i <= m; i ++) {
        q[i] = (ques) {read(), read(), read(), read(), i};
    }
    sort(q + 1, q + m + 1, cmp);
    int l = 1, r = 0;
    for(int i = 1; i <= m; i ++) {
        int ql = q[i].l, qr = q[i].r, opt = q[i].opt, x = q[i].x;
        while(l < ql) dele(l++);
        while(l > ql) add(--l);
        while(r < qr) add(++r);
        while(r > qr) dele(r--);
        if(opt == 1) {
            ans[q[i].id] = (s1 & (s1 >> x)).any();
        }
        if(opt == 2) {
            ans[q[i].id] = (s1 & (s2 >> (n - x))).any();
        }
        if(opt == 3) {
            for(int k = 1; k * k <= x; k ++) {
                if(x % k == 0) {
                    if(s1[k] && s1[x / k]) {
                        ans[q[i].id] = 1;
                        break;
                    }
                }
            }
        }
    }
    for(int i = 1; i <= m; i ++) {
        puts(ans[i] ? "hana" : "bi");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/henry-1202/p/10201959.html