[题解]不会真有人要打树套树吧

校长者,真神人也,左马桶,右永神,会执利笔破邪炁,何人当之?The principal is really a godwith a closestool on the left and Yongshen on the rightholding a sharp pen to pierce the truthWho can resist him? 校長は本当に神であり、左側にトイレ、右側にヨンシェンがあり鋭いペンを持って真実を突き刺している。誰が彼に抵抗できるだろうか? Le principal est vraiment un dieuavec des toilettes à gauche et Yongshen à droitetenant un stylo pointu pour percer la véritéQui peut lui résister ? Der Direktor ist wirklich ein Gottmit einer Toilette links und Yongshen rechtsder einen spitzen Stift hältum die Wahrheit zu durchdringen.Wer kann ihm widerstehen? Principalis deus est, Yongshen a dextris cum latrinaacuto stylo ad perforandum veritatem: quis resistet ei? 对曰:“无人,狗欲当之,还请赐教!”

  BackToTheMenu.

2022-03-19 不会真有人要打树套树吧

  T2 花的时间太多了,还是不大行。

太阳照常升起 / Lost

  注意到 τ(n) 是个完全积性函数,而 ξ=τ1,那 ξ(n) 也就是积性函数。由于 ξ(p)(pP),因此,你会发现 ξ(n) 有值当且仅当 n 为完全平方数,且此时 ξ(n)=1.

  因此现在的问题就变成了求可重集 {ij|1in,1jm} 中有多少是完全平方数,由经典结论:若 ab 为完全平方数,那么存在 m,s,t 使得 ms2=a,mtb=bμ(m)0(即 m 中不含平方因子),因此,我们可以考虑枚举这个 m

i=1nnimiμ2(i)

  其中含有 μ2(i) 是指我们只统计 μ(i)0i. 走到这一步之后,你可以使用 O(n) 的复杂度来解决这个问题,只是你需要求得 μ2(i),这个东西挺困难,因此我们需要将其再一步变形,,考虑使用一个替换:μ2(i)=d2iμ(d),其证明可以使用贝尔级数:

  不难知道 μp2(z)=1+z,μp(z)=1z,1p(z)=11z,因此 μp2(z)=μp(z2)×1p(z),其中 μp(z2) 即要求 d2i,然后就是 μ 卷上 1.

  然后继续推式子:

()=i=1nnimid2iμ(d)=d=1nμ(d)i=1nnid2mid2

  注意后面的根号部分可以数论分块,此时总复杂度就是 O(nlnn). 但是宋队积出来发现时间复杂度只是 O(n) 的,并不明白对数是哪里来的。

/** @author __Elaina__ */

// #pragma GCC optimize("O2")

#include <bits/stdc++.h>
using namespace std;

#define USING_FREAD
// #define NDEBUG
#include <cassert>

namespace Elaina {
/** その可憐な少女は魔女であり、旅人でした。 ―― そう、私です! */

#define rep(i, l, r) for(int i = (l), i##_end_ = (r); i <= i##_end_; ++i)
#define repf(i, l, r) for (int i = (l), i##_end_ = (r); i < i##_end_; ++i)
#define drep(i, l, r) for(int i = (l), i##_end_ = (r); i >= i##_end_; --i)
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)
#define Endl putchar('\n')
#define whole(v) ((v).begin()), ((v).end())
#define bitcnt(s) (__builtin_popcount(s))
/** @warning no forced type conversion */
#define rqr(x) ((x) * (x))
#define y0 FUCK_UP
#define y1 MOTHER_FUCKER
#define masdf(...) fprintf(stderr, __VA_ARGS__)

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

template<class T> inline T fab(T x) { return x < 0 ? -x : x; }
template<class T> inline void chkmin(T& x, const T rhs) { x = std::min(x, rhs); }
template<class T> inline void chkmax(T& x, const T rhs) { x = std::max(x, rhs); }

#ifdef USING_FREAD
inline char qkgetc() {
# define BUFFERSIZE 1 << 20
    static char BUF[BUFFERSIZE], *p1 = BUF, *p2 = BUF;
    return p1 == p2 && (p2 = (p1 = BUF) + fread(BUF, 1, BUFFERSIZE, stdin), p1 == p2) ? EOF : *p1++;
# undef BUFFERSIZE
}
# define CHARRECEI qkgetc()
#else
# define CHARRECEI ((char)getchar())
#endif

template<class T> inline T readret(T x) {
    x = 0; int f = 0; char c;
    while (!isdigit(c = CHARRECEI)) if(c == '-') f = 1;
    for (x = (c ^ 48); isdigit(c = CHARRECEI); x = (x << 1) + (x << 3) + (c ^ 48));
    return f ? -x : x;
}
template<class T> inline void readin(T& x) {
    x = 0; int f = 0; char c;
    while (!isdigit(c = CHARRECEI)) if (c == '-') f = 1;
    for (x = (c ^ 48); isdigit(c = CHARRECEI); x = (x << 1) + (x << 3) + (c ^ 48));
    if (f) x = -x;
}
template<class T, class... Args> inline void readin(T& x, Args&... args) {
    readin(x), readin(args...);
}
template<class T> inline void writln(T x, char c = '\n') {
    if (x < 0) putchar('-'), x = -x;
    static int __stk[55], __bit = 0;
    do __stk[++__bit] = x % 10, x /= 10; while (x);
    while (__bit) putchar(__stk[__bit--] ^ 48);
    putchar(c);
}
template<class T> inline T listMax(const T& x) { return x; }
template<class T, class... Args> inline T listMax(const T& x, const Args&... args) {
    return max(x, listMax(args...));
}
template<class T> inline T listMin(const T& x) { return x; }
template<class T, class... Args> inline T listMin(const T& x, const Args&... args) {
    return min(x, listMin(args...));
}

} // namespace Elaina
using namespace Elaina;

// int tau[Maxn + 5], prime[Maxn + 5];
// bool vis[Maxn + 5];
// int xi[Maxn + 5];
// inline void prelude() {
//     vis[1] = true, tau[1] = 1;
//     rep (i, 2, Maxn) {
//         if (!vis[i]) prime[++*prime] = i, tau[i] = -1;
//         for (int j = 1; j <= *prime && i * prime[j] <= Maxn; ++j) {
//             vis[i * prime[j]] = true;
//             tau[i * prime[j]] = -tau[i];
//             if (i % prime[j] == 0) break;
//         }
//     }
//     // rep (i, 1, Maxn) masdf("tau[%d] == %d\n", i, tau[i]);
//     rep (i, 1, Maxn) {
//         for (int d = 1; d * d <= i; ++d) if (i % d == 0) {
//             xi[i] += tau[d];
//             if (i != d * d) xi[i] += tau[i / d];
//         }
//         if (xi[i] != 0) printf("xi[%d] == %d\n", i, xi[i]);
//     }
// }

const int Maxn = 1e6;

bool vis[Maxn + 5];
int prime[Maxn + 5], mu[Maxn + 5];

inline void prelude() {
    vis[1] = true, mu[1] = 1;
    rep (i, 2, Maxn) {
        if (!vis[i]) prime[++*prime] = i, mu[i] = -1;
        for (int j = 1; j <= *prime && i * prime[j] <= Maxn; ++j) {
            vis[i * prime[j]] = true, mu[i * prime[j]] = -mu[i];
            if (i % prime[j] == 0) { mu[i * prime[j]] = 0; break; }
        }
    }
}

ll n, m;

inline ll work(ll n, ll m) {
    ll ret = 0;
    for (ll l = 1, r; l <= n; l = r + 1) {
        r = min(n / (n / l), m / (m / l));
        ret += (ll)sqrt(n / l) * (ll)sqrt(m / l) * (r - l + 1);
    }
    return ret;
}

signed main() {
    freopen("lost.in", "r", stdin);
    freopen("lost.out", "w", stdout);
    prelude();
    readin(n, m);
    if (n > m) swap(n, m);
    ll ans = 0;
    for (ll i = 1; i * i <= n; ++i) if (mu[i])
        ans += mu[i] * work(n / (i * i), m / (i * i));
    writln(ans);
    return 0;
}

丧钟为谁而鸣 / Harmony

  注意到 p20,因此,若我们随机一次,某个答案没有被随机到的概率为 80%,如果多来几次,比如来 60 次,这个概率将会变成 p=(0.8)601.53249554×106. 因此,我们可以随机取一个区间中的数,然后数这个数在该区间中的出现次数。

  对于数字的统计考虑使用分块,注意在处理散块的时候要顺便将该散块的桶同时清空,总复杂度就是 O(mn×60).

/** @author __Elaina__ */

#pragma GCC optimize("Ofast")

#include <bits/stdc++.h>
using namespace std;

#define USING_FREAD
// #define NDEBUG
#include <cassert>

namespace Elaina {
/** その可憐な少女は魔女であり、旅人でした。 ―― そう、私です! */

#define rep(i, l, r) for(int i = (l), i##_end_ = (r); i <= i##_end_; ++i)
#define repf(i, l, r) for (int i = (l), i##_end_ = (r); i < i##_end_; ++i)
#define drep(i, l, r) for(int i = (l), i##_end_ = (r); i >= i##_end_; --i)
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)
#define Endl putchar('\n')
#define whole(v) ((v).begin()), ((v).end())
#define bitcnt(s) (__builtin_popcount(s))
/** @warning no forced type conversion */
#define rqr(x) ((x) * (x))
#define y0 FUCK_UP
#define y1 MOTHER_FUCKER
#define masdf(...) fprintf(stderr, __VA_ARGS__)

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

template<class T> inline T fab(T x) { return x < 0 ? -x : x; }
template<class T> inline void chkmin(T& x, const T rhs) { x = std::min(x, rhs); }
template<class T> inline void chkmax(T& x, const T rhs) { x = std::max(x, rhs); }

#ifdef USING_FREAD
inline char qkgetc() {
# define BUFFERSIZE 1 << 20
    static char BUF[BUFFERSIZE], *p1 = BUF, *p2 = BUF;
    return p1 == p2 && (p2 = (p1 = BUF) + fread(BUF, 1, BUFFERSIZE, stdin), p1 == p2) ? EOF : *p1++;
# undef BUFFERSIZE
}
# define CHARRECEI qkgetc()
#else
# define CHARRECEI ((char)getchar())
#endif

template<class T> inline T readret(T x) {
    x = 0; int f = 0; char c;
    while (!isdigit(c = CHARRECEI)) if(c == '-') f = 1;
    for (x = (c ^ 48); isdigit(c = CHARRECEI); x = (x << 1) + (x << 3) + (c ^ 48));
    return f ? -x : x;
}
template<class T> inline void readin(T& x) {
    x = 0; int f = 0; char c;
    while (!isdigit(c = CHARRECEI)) if (c == '-') f = 1;
    for (x = (c ^ 48); isdigit(c = CHARRECEI); x = (x << 1) + (x << 3) + (c ^ 48));
    if (f) x = -x;
}
template<class T, class... Args> inline void readin(T& x, Args&... args) {
    readin(x), readin(args...);
}
template<class T> inline void writln(T x, char c = '\n') {
    if (x < 0) putchar('-'), x = -x;
    static int __stk[55], __bit = 0;
    do __stk[++__bit] = x % 10, x /= 10; while (x);
    while (__bit) putchar(__stk[__bit--] ^ 48);
    putchar(c);
}
template<class T> inline T listMax(const T& x) { return x; }
template<class T, class... Args> inline T listMax(const T& x, const Args&... args) {
    return max(x, listMax(args...));
}
template<class T> inline T listMin(const T& x) { return x; }
template<class T, class... Args> inline T listMin(const T& x, const Args&... args) {
    return min(x, listMin(args...));
}

} // namespace Elaina
using namespace Elaina;

const int Maxm = 3e4;
const int Maxn = 1e5 + 3e4 + 5;
const int Blo = 320;

// const int Maxm = 100;
// const int Maxn = 100;
// const int Blo = 1;

int a[Maxn + 5], n, m, perc;
int blef[Maxn / Blo + 5], brig[Maxn / Blo + 5], bel[Maxn + 5], bcnt;
int tag[Maxn / Blo + 5]; // the number which cover the block

int op[Maxn + 5], ql[Maxn + 5], qr[Maxn + 5], qt[Maxn + 5];
int arr[Maxn + 5], siz;

int buc[Maxn / Blo + 5][Maxn + 5];

inline void prelude() {
    sort(arr + 1, arr + siz + 1);
    siz = unique(arr + 1, arr + siz + 1) - arr - 1;
    memset(tag, 0xff, sizeof tag);

    rep (i, 1, n) a[i] = lower_bound(arr + 1, arr + siz + 1, a[i]) - arr;
    rep (i, 1, m) if (op[i] == 1) qt[i] = lower_bound(arr + 1, arr + siz + 1, qt[i]) - arr;

    for (int i = 1; (i - 1) * Blo + 1 <= n; ++i) {
        bcnt = i;
        blef[i] = (i - 1) * Blo + 1, brig[i] = min(i * Blo, n);
        rep (j, blef[i], brig[i]) bel[j] = i, ++buc[i][a[j]];
    }
}

inline void filbuc(int id, int x) {
    rep (i, blef[id], brig[id]) buc[id][a[i]] += x;
}
inline void pushdown(int id) {
    if (!~tag[id]) return ;
    rep (j, blef[id], brig[id]) {
        --buc[id][a[j]];
        ++buc[id][a[j] = tag[id]];
    }
    tag[id] = -1;
}
inline void update(int ql, int qr, int x) {
    if (bel[ql] == bel[qr]) {
        pushdown(bel[ql]);
        rep (i, ql, qr) {
            --buc[bel[ql]][a[i]];
            ++buc[bel[ql]][a[i] = x];
        }
        return ;
    }
    pushdown(bel[ql]), pushdown(bel[qr]);
    rep (i, ql, brig[bel[ql]]) {
        --buc[bel[ql]][a[i]];
        ++buc[bel[ql]][a[i] = x];
    }
    rep (i, bel[ql] + 1, bel[qr] - 1) tag[i] = x;
    rep (i, blef[bel[qr]], qr) {
        --buc[bel[qr]][a[i]];
        ++buc[bel[qr]][a[i] = x];
    }
    return ;
}
inline int query(int ql, int qr, int x) {
    int ret = 0;
    if (bel[ql] == bel[qr]) {
        pushdown(bel[ql]);
        rep (i, ql, qr) ret += (a[i] == x);
        return ret;
    }
    pushdown(bel[ql]), pushdown(bel[qr]);
    rep (i, ql, brig[bel[ql]]) ret += (a[i] == x);
    rep (i, bel[ql] + 1, bel[qr] - 1) {
        if (tag[i] == -1) ret += buc[i][x];
        else ret += (tag[i] == x) * (brig[i] - blef[i] + 1);
    }
    rep (i, blef[bel[qr]], qr) ret += (a[i] == x);
    return ret;
}

mt19937 rnd(0xcbdd1);
// inline ull regen() {
//     return ((rnd() ^ rnd() | rnd() & rnd()) & 0x7fff) << 15 | ((rnd() ^ rnd() | rnd() & rnd()) & 0x7fff);
// }
inline int gen(int l, int r) {
    return rnd() % (r - l + 1) + l;
}
unordered_map<int, bool> used;
int ans[Maxn + 5], ans_siz;
inline void solve(int ql, int qr) {
    int mxx = 0, len = qr - ql + 1;
    used.clear(), ans_siz = 0;
    rep (_, 1, 100) {
        int p = gen(ql, qr);
        if (used.count(p)) continue;
        used[p] = true;
        p = (tag[bel[p]] == -1? a[p]: tag[bel[p]]);
        int cnt = query(ql, qr, p);

        if (cnt * 100 < len * perc) continue;

        if (cnt > mxx) ans[ans_siz = 1] = p, mxx = cnt;
        else if (cnt == mxx) ans[++ans_siz] = p;

        // if (ans_siz == 100 / perc) break;

        if ((int)used.size() >= 60) break;
    }
    sort(ans + 1, ans + ans_siz + 1);
    ans_siz = unique(ans + 1, ans + ans_siz + 1) - ans - 1;
    writln(ans_siz, ' ');
    rep (i, 1, ans_siz) writln(arr[ans[i]], ' ');
    Endl;
}

inline void work() {
    rep (i, 1, m) {
        if (op[i] == 1) update(ql[i], qr[i], qt[i]);
        else solve(ql[i], qr[i]);
    }
}

signed main() {
    freopen("harmony.in", "r", stdin);
    freopen("harmony.out", "w", stdout);
    readin(n, m, perc);
    rep (i, 1, n) readin(a[i]), arr[++siz] = a[i];
    rep (i, 1, m) {
        readin(op[i], ql[i], qr[i]);
        if (op[i] == 1) readin(qt[i]), arr[++siz] = qt[i];
    }
    prelude();
    work();
    return 0;
}

老人与海 / Dignity

  注意每种武器的 OGF 为 11xai,因此

f(T)=[xT]i=1n11xai

  但是他们全是分式,不是特别好处理,令 W=lcm(ai),那么,我们可以将原式写成:

f(T)=[xT]1(1xW)ni=1n1xW1xai=[xT](i=0+xiW)ni=1n(j=0(W/ai)1xj×ai)

  这个多项式考虑分成两个部分:(i=0+xiW)ni=1n(j=0(W/ai)1xj×ai),前半部分只有 xiW 项,并且其系数为 (n+i1i1),后半部分是一个次数很低的多项式,可以直接做多项式乘法得到,记前者为多项式 Q,后者为多项式 P.

  于是,可以将 T=kW+r,记 f(T)=G(k,r),并且对于 G(k,r),我们有

G(k,r)=i=0kq((ki)W)+p(iW+r)=i=0k(n+ki1n1)p(iW+r)

  在原问题中,我们要找到最小的 T 使得 f(T)hi,只需要对每个 modW 的余数都做一次二分即可,因为显然当 r 固定时,G(k,r)k 单增。

  但是为什么会想到用 W 对那个奇奇怪怪的式子进行化简呢?因为它们对 W 构成了 循环,因此我们可以将 + 从每个 后面的 归到对 W 求和的 上,这个过程看上去就是在处理一个长度为 W 的循环了。

/** @author __Elaina__ */

#pragma GCC optimize("Ofast")

#include <bits/stdc++.h>
using namespace std;

#define USING_FREAD
// #define NDEBUG
#include <cassert>

namespace Elaina {
/** その可憐な少女は魔女であり、旅人でした。 ―― そう、私です! */

#define rep(i, l, r) for(int i = (l), i##_end_ = (r); i <= i##_end_; ++i)
#define repf(i, l, r) for (int i = (l), i##_end_ = (r); i < i##_end_; ++i)
#define drep(i, l, r) for(int i = (l), i##_end_ = (r); i >= i##_end_; --i)
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)
#define Endl putchar('\n')
#define whole(v) ((v).begin()), ((v).end())
#define bitcnt(s) (__builtin_popcount(s))
/** @warning no forced type conversion */
#define rqr(x) ((x) * (x))
#define y0 FUCK_UP
#define y1 MOTHER_FUCKER
#define masdf(...) fprintf(stderr, __VA_ARGS__)

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

template<class T> inline T fab(T x) { return x < 0 ? -x : x; }
template<class T> inline void chkmin(T& x, const T rhs) { x = std::min(x, rhs); }
template<class T> inline void chkmax(T& x, const T rhs) { x = std::max(x, rhs); }

#ifdef USING_FREAD
inline char qkgetc() {
# define BUFFERSIZE 1 << 20
    static char BUF[BUFFERSIZE], *p1 = BUF, *p2 = BUF;
    return p1 == p2 && (p2 = (p1 = BUF) + fread(BUF, 1, BUFFERSIZE, stdin), p1 == p2) ? EOF : *p1++;
# undef BUFFERSIZE
}
# define CHARRECEI qkgetc()
#else
# define CHARRECEI ((char)getchar())
#endif

template<class T> inline T readret(T x) {
    x = 0; int f = 0; char c;
    while (!isdigit(c = CHARRECEI)) if(c == '-') f = 1;
    for (x = (c ^ 48); isdigit(c = CHARRECEI); x = (x << 1) + (x << 3) + (c ^ 48));
    return f ? -x : x;
}
template<class T> inline void readin(T& x) {
    x = 0; int f = 0; char c;
    while (!isdigit(c = CHARRECEI)) if (c == '-') f = 1;
    for (x = (c ^ 48); isdigit(c = CHARRECEI); x = (x << 1) + (x << 3) + (c ^ 48));
    if (f) x = -x;
}
template<class T, class... Args> inline void readin(T& x, Args&... args) {
    readin(x), readin(args...);
}
template<class T> inline void writln(T x, char c = '\n') {
    if (x < 0) putchar('-'), x = -x;
    static int __stk[55], __bit = 0;
    do __stk[++__bit] = x % 10, x /= 10; while (x);
    while (__bit) putchar(__stk[__bit--] ^ 48);
    putchar(c);
}
template<class T> inline T listMax(const T& x) { return x; }
template<class T, class... Args> inline T listMax(const T& x, const Args&... args) {
    return max(x, listMax(args...));
}
template<class T> inline T listMin(const T& x) { return x; }
template<class T, class... Args> inline T listMin(const T& x, const Args&... args) {
    return min(x, listMin(args...));
}

} // namespace Elaina
using namespace Elaina;

const int Maxn = 1e5;
const ll inf = 1ll << 60;

int a[Maxn + 5], n, W = 1, q;

int p[Maxn + 5], m;

inline void input() {
    readin(n);
    rep (i, 1, n) {
        readin(a[i]);
        int g = __gcd(a[i], W);
        W = W / g * a[i];
    }
    // masdf("W == %d\n", W);
}

int tmp[Maxn + 5];
inline void solveP() {
    p[0] = 1, m = 1;
    rep (i, 1, n) {
        int mxp = 0;
        repf (j, 0, m) if (p[j])
            repf (t, 0, W / a[i])
                tmp[j + t * a[i]] += p[j], chkmax(mxp, j + t * a[i]);
        chkmax(m, mxp + 1);
        memcpy(p, tmp, m << 2);
        memset(tmp, 0, m << 2);
    }
    // repf (i, 0, m) masdf("%d ", p[i]); Endl;
}

inline ll C(ll n, ll m) {
    ll ret = 1;
    for (int i = 1; i <= m; ++i, --n)
        ret *= n;
    rep (i, 1, m) ret /= i;
    return ret;
}

inline ll check(ll k, int r, const ll& tar) {
    ll fun_val = 0;
    for (int i = 0; ; ++i) {
        int now = i * W + r;
        if (now >= m) break;
        if (!p[now]) continue; // useless
        // to avoid ll leak
        ll res = tar - fun_val;
        repf (t, 1, n) res *= t;
        res /= p[now];
        repf (t, 1, n) {
            if (n + k - i - t == 0) { res = inf; break; }
            res /= (n + k - i - t);
        }
        if (res <= 0) return true;

        fun_val += C(n + k - i - 1, n - 1) * p[now];
    }
    return fun_val >= tar;
}

signed main() {
    freopen("dignity.in", "r", stdin);
    freopen("dignity.out", "w", stdout);
    input();
    solveP();
    readin(q);
    while (q--) {
        ll h, ans = inf; readin(h);
        repf (r, 0, W) {
            ll pl = 0, pr = min((100 * h - r) / W, (ans - r) / W);
            if (!check(pr, r, h)) continue;
            ll resk = -1;
            for (ll mid = pl + pr >> 1; pl <= pr; mid = pl + pr >> 1)
                if (check(mid, r, h)) resk = mid, pr = mid - 1;
                else pl = mid + 1;
            if (~resk) chkmin(ans, resk * W + r);
        }
        if (ans == inf) puts("What a pity!");
        else writln(ans);
    }
    return 0;
}
posted @   Arextre  阅读(131)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示