1. 程式人生 > >LuoguP3674 小清新人渣的本願

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;
}