Codeforces Round #678 (Div. 2)
A
观察发现, 和顺序无关
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> n >> m; ll sum = 0;
rep (i, 1, n) cin >> k, sum += k;
if (sum == m) cout << "YES\n";
else cout << "NO\n";
}
return 0;
}
B
简单构造
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> n; memset(a, 0, sizeof a);
if (n & 1) {
rep (i, 1, n) a[i][i] = 1, a[i][i + 1] = 4;
a[n][1] = 4;
}
else for (int i = 1; i <= n; i += 2) a[i][i] = a[i][i + 1] = a[i + 1][i] = a[i + 1][i + 1] = 1;
rep (i, 1, n) {
rep (j, 1, n) cout << a[i][j] << ' ', a[i][j] = 0;
cout << '\n';
}
}
return 0;
}
C
按正确的二分走一遍, 找到通过二分比较, 需要多少个 大于 这个数的 和多少个小于这个数的
然后组合数学
int n, m, _, k;
ll inv[N] = {0, 1}, a[N] = {1, 1}, b[N] = {1, 1};
VI fa;
void init(int n, int p = mod) {
rep (i, 2, n) {
inv[i] = (ll)(p - p / i) * inv[p % i] % p;
a[i] = (ll)a[i - 1] * i % p;
b[i] = (ll)b[i - 1] * inv[i] % p;
}
}
PII work(int k) {
int l = 1, r = n + 1, x = 0, y = 0;
while (l < r) {
int mid = l + r >> 1;
if (mid <= k) l = mid + 1, ++x;
else r = mid, ++y;
}
return { --x, y };
}
int main() {
IOS; init(1e3);
cin >> n >> m >> k;
PII p = work(k + 1);
ll ans = 0;
if (n - m - p.se >= 0 && m - 1 - p.fi >= 0 && n - p.se - p.fi - 1 >= 0)
ans = a[n - m] * b[n - m - p.se] % mod * a[m - 1] % mod * b[m - 1 - p.fi] % mod * a[n - p.se - p.fi - 1] % mod;
cout << ans << '\n';
return 0;
}
D
题都没读懂, 土匪走的单行道, 居民可以任意走.....原来居民可以任意走啊.....
int main() {
IOS; cin >> n;
vector<ll> a(n + 1), siz(n + 1, 1), from(n + 1);
rep (i, 2, n) cin >> from[i], siz[from[i]] = 0;
rep (i, 1, n) cin >> a[i];
ll ans = 0;
per (i, n, 1) {
umax(ans, (a[i] - 1 + siz[i]) / siz[i]);
a[from[i]] += a[i]; siz[from[i]] += siz[i];
}
cout << ans;
return 0;
}
E
找 a[i] 是否可以选入 mex 集
i 左边存在 1~a[i]-1, 或者 x 右边存在 1~a[i]-1, 或者 两边合在一起存在 1~a[i]-1
前两种其实都属于最后一种
最后一种最不好处理, 但我们可以隔空处理, 对于 i 的左右, 我们直接将 i 这个位置转移到 上一次出现 a[i] 的位置 x, 则 x + 1 ~ n就是 i 左右的合集
剩下的就好做了
注意特殊处理 1, 只有在存在 a[i] > 1 的时候 1 才能取到
int h[N], ne[N], a[N], c[N];
bool v[N];
void add(int x, int k) {
for (; x <= n; x += -x & x) umin(c[x], k);
}
int ask(int x) {
int ans = n;
for (; x; x -= -x & x) umin(ans, c[x]);
return ans;
}
int main() {
IOS; cin >> n;
rep (i, 1, n) cin >> a[i], ne[i] = h[a[i]], h[a[i]] = i, c[i] = n;
rep (i, 1, n) add(i, h[i]);
rep (i, 2, n + 1) if (ask(i - 1) > h[i]) v[i] = 1;
per (i, n, 1) {
add(a[i], ne[i]);
if (a[i] - 1 && ask(a[i] - 1) > ne[i]) v[a[i]] = 1;
if (a[i] - 1) v[1] = 1;
}
int ans = 0; while (v[++ans]); cout << ans;
return 0;
}