[Ynoi2017]チームによるbzoj4810は、トウモロコシ畑のMo +ビットセット(+数論)であります

トピックポータル

https://lydsy.com/JudgeOnline/problem.php?id=4810

問題の解決策

データ範囲を見てください名前とタイトルこれは、ルートアルゴリズムでなければなりません。

呼び掛けゾーン、並びに第一以来また\(3 \)のパラメータは、ブロックされにくいです。

だから、Moのメンテナンスのためのチームをオフライン考えます。

経験によると、シフト判断の有無の数の差の値は、ビットセットがあります。存在する場合、それは減算に変換することができる現在の間隔内のすべての数のメンテナンスビットセットは\(S \&(S << X))\) 空の判定です。

次いで添加は、同様の決意の減算ロールオーバーをビットセットすることができます。

乗算ワードは、製品ため\(\のLeq C \)は、することができる\(\ SQRT C \)各因子の列挙が決定されます。


合計時間の複雑さである(O(M(\ + N-SQRT \ FRAC C {64}))\)\します

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back

template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}

typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;

template<typename I> inline void read(I &x) {
    int f = 0, c;
    while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    x = c & 15;
    while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    f ? x = -x : 0;
}

const int N = 100000 + 7;
const int M = 100000;

#define bl(x) (((x) - 1) / blo + 1)

int n, m, blo;
int a[N], ans[N], cnt[N];
std::bitset<N> s, t;

struct Query {
    int opt, l, r, x, *ans;
    inline bool operator < (const Query &b) const { return bl(l) != bl(b.l) ? l < b.l : r < b.r; }
} q[N];

inline void madd(int x) {
    ++cnt[a[x]];
    if (cnt[a[x]] == 1) s.set(a[x]), t.set(M - a[x]);
}
inline void mdel(int x) {
    --cnt[a[x]];
    if (!cnt[a[x]]) s.reset(a[x]), t.reset(M - a[x]);
}

inline void work() {
    std::sort(q + 1, q + m + 1);
    int l = 1, r = 0;
    for (int i = 1; i <= m; ++i) {
        while (l > q[i].l) madd(--l);
        while (r < q[i].r) madd(++r);
        while (l < q[i].l) mdel(l++);
        while (r > q[i].r) mdel(r--);
        if (q[i].opt == 1) *q[i].ans = (s & (s << q[i].x)).any();
        else if (q[i].opt == 2) *q[i].ans = (t & (s << (M - q[i].x))).any();
        else {
            int x = q[i].x;
            for (int j = 1, p = sqrt(x); j <= p; ++j)
                if (x % j == 0 && s[j] && s[x / j]) { *q[i].ans = 1; break; }
        }
    }
    for (int i = 1; i <= m; ++i) if (ans[i]) puts("yuno"); else puts("yumi");
}

inline void init() {
    read(n), read(m), blo = sqrt(n);
    for (int i = 1; i <= n; ++i) read(a[i]);
    for (int i = 1; i <= m; ++i) read(q[i].opt), read(q[i].l), read(q[i].r), read(q[i].x), q[i].ans = ans + i;
}

int main() {
#ifdef hzhkk
    freopen("hkk.in", "r", stdin);
#endif
    init();
    work();
    fclose(stdin), fclose(stdout);
    return 0;
}

おすすめ

転載: www.cnblogs.com/hankeke/p/bzoj4810.html