# AtCoder Grand Contest 005

## A - STring

#include <cstdio>

const int MN = 200005;

char s[MN], t[MN];
int tp;

int main() {
scanf("%s", s + 1);
for (int i = 1; s[i]; ++i) {
if (tp && t[tp] == 'S' && s[i] == 'T') --tp;
else t[++tp] = s[i];
}
printf("%d\n", tp);
return 0;
}


## B - Minimum Sum

#include <cstdio>

typedef long long LL;
const int MN = 200005;

int N, A[MN], L[MN], R[MN];
int stk[MN], tp;
LL Ans;

int main() {
scanf("%d", &N);
for (int i = 1; i <= N; ++i) scanf("%d", &A[i]);
stk[tp = 1] = 0;
for (int i = 1; i <= N; ++i) {
while (A[stk[tp]] > A[i]) R[stk[tp--]] = i;
L[i] = stk[tp], stk[++tp] = i;
}
while (tp) R[stk[tp--]] = N + 1;
for (int i = 1; i <= N; ++i) Ans += (LL)(i - L[i]) * (R[i] - i) * A[i];
printf("%lld\n", Ans);
return 0;
}


## C - Tree Restoring

#include <cstdio>
#include <algorithm>

const int MN = 105;

int N, A[MN], B[MN];

int main() {
scanf("%d", &N);
for (int i = 1; i <= N; ++i) scanf("%d", &A[i]), ++B[A[i]];
std::sort(A + 1, A + N + 1);
int len = A[N];
for (int i = 0; i <= len; ++i) --B[std::max(len - i, i)];
for (int i = 1; i <= N; ++i) if (B[i] < 0) return puts("Impossible"), 0;
int hlen = (len + 1) / 2;
for (int i = 1; i <= hlen; ++i) if (B[i]) return puts("Impossible"), 0;
puts("Possible");
return 0;
}


## D - ~K Perm Counting

#include <cstdio>

typedef long long LL;
const int Mod = 924844033;
const int MN = 2005;

int N, K;
int A[MN * 2], M;
int f[2][2][MN];

int main() {
scanf("%d%d", &N, &K);
for (int i = 1; i <= K; ++i) {
for (int j = i; j <= N; j += K) A[++M] = j != i;
for (int j = i; j <= N; j += K) A[++M] = j != i;
}
int o = 0;
f[0][0][0] = 1;
for (int i = 1; i <= M; ++i) {
o ^= 1;
for (int j = 0; j <= N; ++j) {
f[o][0][j] = f[o][1][j] = 0;
f[o][0][j] = (f[o ^ 1][0][j] + f[o ^ 1][1][j]) % Mod;
if (A[i] && j)
f[o][1][j] = f[o ^ 1][0][j - 1];
}
}
int Coef = 1, Ans = 0;
for (int i = N; i >= 0; --i) {
Ans = (Ans + (i & 1 ? -1ll : 1ll) * Coef * (f[o][0][i] + f[o][1][i])) % Mod;
Coef = (LL)Coef * (N - i + 1) % Mod;
}
printf("%d\n", (Ans + Mod) % Mod);
return 0;
}


## E - Sugigma: The Showdown

Sigma 到达了一条红边的两端点之一，这条红边的两端点在蓝树上的距离大于等于 $3$，且 Sugim 下一步无法直接抓到 Sigma。

#include <cstdio>
#include <vector>

const int MN = 200005;

int N, X, Y, Ans;
std::vector<int> G[2][MN];

int par[MN], dep[MN];
void DFS0(int u, int p) {
dep[u] = dep[par[u] = p] + 1;
for (int v : G[1][u]) if (v != p) DFS0(v, u);
}

void DFS1(int u, int p, int d) {
int win = 0;
Ans = std::max(Ans, dep[u]);
for (int v : G[0][u]) if (v != p) {
if (u == par[v] || v == par[u] || u == par[par[v]] || v == par[par[u]] || par[u] == par[v]) {
if (d + 1 < dep[v]) DFS1(v, u, d + 1);
} else { win = 1; break; }
}
if (win) Ans = N;
}

int main() {
scanf("%d%d%d", &N, &X, &Y);
for (int o = 0; o < 2; ++o)
for (int i = 1, x, y; i < N; ++i)
scanf("%d%d", &x, &y),
G[o][x].push_back(y),
G[o][y].push_back(x);
dep[0] = -1, DFS0(Y, 0);
DFS1(X, 0, 0);
printf("%d\n", Ans == N ? -1 : 2 * Ans);
return 0;
}


## F - Many Easy Problems

$K$ 的答案反正就是 $\displaystyle N \binom{N}{K}$ 减去 $\displaystyle \sum b_i \binom{i}{K}$，此处 $b_i$ 就是大小为 $i$ 的子树个数。

#include <cstdio>

inline void swap(int &x, int &y) { x ^= y ^= x ^= y; }

typedef long long LL;
const int MN = 200005;
const int MS = 524288;
const int Mod = 924844033;
const int G = 5, iG = 554906420;

inline int qPow(int b, int e) {
int a = 1;
for (; e; b = (LL)b * b % Mod, e >>= 1)
if (e & 1) a = (LL)a * b % Mod;
return a;
}

int Inv[MN], Fac[MN], iFac[MN];
int R[MS];

void Init(int N) {
Inv[1] = 1;
for (int i = 2; i <= N; ++i) {
Inv[i] = (LL)(Mod - Mod / i) * Inv[Mod % i] % Mod;
}
Fac[0] = iFac[0] = 1;
for (int i = 1; i <= N; ++i) {
Fac[i] = (LL)Fac[i - 1] * i % Mod;
iFac[i] = (LL)iFac[i - 1] * Inv[i] % Mod;
}
}

void FNTT(int *A, int Sz, int Ty) {
for (int i = 0; i < Sz; ++i)
if (R[i] < i) swap(A[R[i]], A[i]);
for (int j = 1; j < Sz; j <<= 1) {
int j2 = j << 1, wn = qPow(~Ty ? G : iG, (Mod - 1) / j2);
for (int i = 0; i < Sz; i += j2) {
for (int k = 0, w = 1; k < j; ++k, w = (LL)w * wn % Mod) {
int X = A[i + k], Y = (LL)w * A[i + j + k] % Mod;
A[i + k] = X + Y; if (A[i + k] >= Mod) A[i + k] -= Mod;
A[i + j + k] = X - Y; if (A[i + j + k] < 0) A[i + j + k] += Mod;
}
}
}
if (Ty == -1) {
int InvSz = qPow(Sz, Mod - 2);
for (int i = 0; i < Sz; ++i) A[i] = (LL)A[i] * InvSz % Mod;
}
}

int N, A[MS], B[MS];
int h[MN], nxt[MN * 2], to[MN * 2], tot;
inline void ins(int x, int y) {
nxt[++tot] = h[x], to[tot] = y, h[x] = tot;
}

int DFS(int u, int f) {
int sz = 1, sv;
for (int i = h[u]; i; i = nxt[i]) if (to[i] != f) {
sz += sv = DFS(to[i], u);
--A[sv], --A[N - sv];
} return sz;
}

int main() {
scanf("%d", &N);
Init(N);
for (int i = 1, x, y; i < N; ++i) {
scanf("%d%d", &x, &y);
ins(x, y), ins(y, x);
}
DFS(1, 0), A[N] = N;
for (int i = 1; i <= N; ++i) A[i] = ((LL)A[i] * Fac[i] % Mod + Mod) % Mod;
for (int i = 0; i < N; ++i) B[i] = iFac[N - 1 - i];
int Sz = 1, Bt = 0;
for (; Sz < N + N; Sz <<= 1, ++Bt) ;
for (int i = 0; i < Sz; ++i) R[i] = R[i >> 1] >> 1 | (i & 1) << (Bt - 1);
FNTT(A, Sz, 1), FNTT(B, Sz, 1);
for (int i = 0; i < Sz; ++i) A[i] = (LL)A[i] * B[i] % Mod;
FNTT(A, Sz, -1);
for (int i = 1; i <= N; ++i) printf("%lld\n", (LL)A[i + N - 1] * iFac[i] % Mod);
return 0;
}

posted @ 2020-06-22 23:22  粉兔  阅读(41)  评论(0编辑  收藏