洛谷 P3674 小清新人渣的本愿

https://www.luogu.com.cn/problem/P3674

  • a - b = x 可以转换成 a = b + x.用bitset记录区间数的种类,存在a - b = x 等价于 bitset & bitset<<x 是否有1
  • a + b = x 可以记b = N - B,也就是判断 a - B = x - N是否存在,另外记录一个bitset就能转化到两数之差
  • a * b = x 直接枚举因子即可
codes
const int maxn = 1e5 + 7;

int n, t, m, k;
int a[maxn], ans[maxn];

struct query {
    int id, op, x, l, r;
} q[maxn];

bool cmp(query a, query b) {
    if (a.l / k == b.l / k)
        return a.r < b.r;
    return a.l / k < b.l / k;
}

bitset<maxn> now, eth;
int cnt[maxn], nct[maxn];

void add(int x) {
    cnt[x]++, nct[maxn - x]++;
    now.set(x);
    eth.set(maxn - x);
}

void del(int x) {
    cnt[x]--, nct[maxn - x]--;
    if (cnt[x] == 0)
        now.reset(x);
    if (nct[maxn - x] == 0)
        eth.reset(maxn - x);
}

void solve() {
    cin >> n >> m;
    k = (int) sqrt(maxn);
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    for (int i = 1; i <= m; i++) {
        cin >> q[i].op >> q[i].l >> q[i].r >> q[i].x;
        q[i].id = i;
    }

    sort(q + 1, q + 1 + m, cmp);

    int l = 1, r = 0;

    for (int i = 1; i <= m; i++) {
        int pl = q[i].l, pr = q[i].r;
        while (l > pl) add(a[--l]);
        while (r < pr) add(a[++r]);
        while (l < pl) del(a[l++]);
        while (r > pr) del(a[r--]);
        if (q[i].op == 1) {
            ans[q[i].id] = (int) (now & (now << q[i].x)).any();
        } else if (q[i].op == 2) {
            ans[q[i].id] = (int) (now & (eth >> (maxn - q[i].x))).any();
        } else {
            for (int c = 1; c * c <= q[i].x; c++) {
                if (q[i].x % c) continue;
                if (now[c] && now[q[i].x / c])
                    ans[q[i].id]++;
            }
        }
    }
    for (int i = 1; i <= m; i++)
        if (ans[i]) cout << "hana" << endl;
        else cout << "bi" << endl;
}
posted @ 2021-08-11 16:03  naymi  阅读(57)  评论(0)    收藏  举报