P2351 [SDOI2012]吊灯
对于能够分成大小为 \(i\) 的若干个联通块,要求至少 \(\lfloor \frac{N}{i} \rfloor\) 个节点子树的 \(size\) 为 \(i\) 的倍数。
这是显然的。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std;
typedef long long ll;
const ll MAXN = 1.2e6+10, D = 19940105;
ll N, M, fa[MAXN], siz[MAXN], sq[MAXN];
vector <ll> q;
int main() {
ios::sync_with_stdio(false);
cin >> N;
for (ll i = 1; i * i <= N; i++) {
if (N % i) continue;
ll tem = N / i;
if (tem != i) {
q.push_back(tem);
}
q.push_back(i);
}
sort(q.begin(), q.end());
for (ll k = 1; k <= 10; k++) {
cout << "Case #" << k << ":\n";
siz[1] = 1;sq[1] = 0;
for (ll j = 2; j <= N; j++) {
siz[j] = 1; sq[j] = 0;
if (k == 1) {
if (j != 2) cin.get();
cin >> fa[j];
} else fa[j] = (fa[j] + D) % (j - 1) + 1;
}
for (ll i = N; i > 1; i--) {
siz[fa[i]] += siz[i];
sq[siz[i]]++;
}
sq[siz[1]]++;
for (unsigned int i = 0; i < q.size(); i++) {
ll ret = 0, now = q.at(i);
for (ll j = 1; now*j <= N; j++) ret += sq[now*j];
if (ret * now >= N) cout << now << '\n';
}
}
return 0;
}
希望我们都有一个光明的未来