由于是ABC, 所以ABC题过于简单就咕咕咕了
D Line++
枚举一下所有组判断一下即可
#include<bits/stdc++.h>
using namespace std;
int n, x, y, ans[10005];
int main()
{
cin >> n >> x >> y;
for(int i = 1; i <= n; i++)
{
for(int j = i + 1; j <= n; j++)
{
int t = min(min(j - i, abs(x - i) + abs(j - x)), min(abs(y - i) + abs(j - y), abs(x - i) + 1 + abs(j - y)));
ans[t]++;
}
}
for(int i = 1; i <= n - 1; i++)
printf("%d
", ans[i]);
return 0;
}
E Red and Green Apples
显然从大到小排好序后最优,无色的苹果不用管它,因为只要你取到个数且不超过限制一定可以通过分配使他满足。(所以代码特别好写)
#include<bits/stdc++.h>
using namespace std;
#define N 500005
int a, b, c, n, X, Y;
long long ans = 0;
struct point
{
int v, id;
bool operator < (const point &o) const
{
return v > o.v;
}
}p[N];
int main()
{
ios::sync_with_stdio(false);
cin >> X >> Y >> a >> b >> c;
n = a + b + c;
for(int i = 1; i <= n; i++)
{
cin >> p[i].v;
if(i <= a) p[i].id = 1;
else if(i <= a + b) p[i].id = 2;
else p[i].id = 3;
}
sort(p + 1, p + n + 1);
int x = 0, y = 0, cnt = 0;
for(int i = 1; i <= n; i++)
{
if(p[i].id == 1)
{
if(x == X) continue;
else x++;
}
else if(p[i].id == 2)
{
if(y == Y) continue;
else y++;
}
ans += 1ll * p[i].v;
cnt++;
if(cnt == X + Y) break;
}
cout << ans << endl;
return 0;
}
F Distributing Integers
来填坑了
赛时没切掉 /kk 我发现我并不会多重集的排列这个东西。
简单介绍一下,令 (S) 为 (k) 种不同类型对象(每种集合里的对象等价)的多重集合,从S中取r个数构成排列的方案数称为 (S) 的 (r) 排列。当 (r = n) 时,有
(P(n, n_1*a_1, ..., n_k*a_k) = frac{(n - 1)!}{prod_{i = 1}^{k}n_k!})
回到这道题,我们首先取1为根,做一遍树形dp, 令 (f[i]) 表示以i为根的树有多少种填数字的方案。
[f[x] =
egin{cases}
frac{(sz[x] - 1)!}{prod_{i in{ch(x)}}{sz[i]!}} imes prod_{i in{ch(x)}}{f[i]} , sz[x] > 1 \
1, sz[x] = 1
end{cases}
]
是叶子结点就是1, 不是叶子结点就是我把每个子树看做一个集合做多重集排列(得出顺序), 然后直接乘每个每个子树的贡献就行。
做完第一次树形dp之后进行换根dp,这一步应该比较简单,只要每次换的时候消除/加入影响即可
#include<bits/stdc++.h>
using namespace std;
#define N 200005
const int mod = 1e9 + 7;
#define add(x, y) (x + y >= mod ? x + y - mod : x + y)
#define dec(x, y) (x < y ? x - y + mod ? x - y)
int n, a[N], head[N], nxt[N << 1], to[N << 1], cnt = 0, sz[N], f[N], fac[N], inv[N], g[N];
int Pow(int x, int k)
{
int base = x, ans = 1;
while(k)
{
if(k & 1) ans = 1ll * ans * base % mod;
base = 1ll * base * base % mod;
k >>= 1;
}
return ans;
}
void adde(int x, int y)
{
cnt++;
to[cnt] = y;
nxt[cnt] = head[x];
head[x] = cnt;
}
void dfs(int x, int fa)
{
sz[x] = 1;
for(int p = head[x]; p; p = nxt[p])
{
int v = to[p];
if(v == fa) continue;
dfs(v, x);
sz[x] += sz[v];
}
f[x] = fac[sz[x] - 1];
for(int p = head[x]; p; p = nxt[p])
{
int v = to[p];
if(v == fa) continue;
f[x] = 1ll * f[x] * inv[sz[v]] % mod * f[v] % mod;
}
}
void dfs2(int x, int fa)
{
for(int p = head[x]; p; p = nxt[p])
{
int v = to[p];
if(v == fa) continue;
int t = 1ll * g[x] * fac[n - 1 - sz[v]] % mod * inv[n - 1] % mod * fac[sz[v]] % mod * Pow(f[v], mod - 2) % mod;
int ns = n - sz[v];
// cout << x << ' ' << v << ' ' << t << ' ' << ns << endl;
g[v] = 1ll * f[v] * t % mod * inv[ns] % mod * fac[n - 1] % mod * inv[sz[v] - 1] % mod;
dfs2(v, x);
}
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n - 1; i++)
{
int x, y;
scanf("%d%d", &x, &y);
adde(x, y), adde(y, x);
}
fac[0] = 1, inv[0] = 1, fac[1] = 1, inv[1] = 1;
for(int i = 2; i <= n; i++) fac[i] = 1ll * fac[i - 1] * i % mod, inv[i] = Pow(fac[i], mod - 2);
dfs(1, 1);
// cout << f[1] << endl;
g[1] = f[1];
dfs2(1, 1);
for(int i = 1; i <= n; i++)
printf("%d
", g[i]);
return 0;
}