# [NOIp 2018]all

## Code

Day1 T1 铺设道路

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

int n, a, la, ans;

int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a);
if (a > la) ans += a-la;
la = a;
}
printf("%d\n", ans);
return 0;
}

Day1 T2 货币系统

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

int t, n, f[25005], a[105], ma, ans;

void work() {
memset(f, ma = 0, sizeof(f));
scanf("%d", &n); ans = n, f[0] = 1;
for (int i = 1; i <= n; i++) scanf("%d", &a[i]), ma = max(a[i], ma);
for (int i = 1; i <= n; i++)
for (int j = a[i]; j <= ma; j++)
if (f[j-a[i]]) f[j]++;
for (int i = 1; i <= n; i++)
ans -= f[a[i]] > 1;
printf("%d\n", ans);
}
int main() {
scanf("%d", &t);
while (t--) work();
return 0;
}

Day1 T3 赛道修建

#include <bits/stdc++.h>
using namespace std;
const int N = 50000+5, inf = 500000000;

int n, m, u, v, l, cnt, mid, vis[N];
struct tt {int nxt, to, dis; } edge[N<<1];
int path[N], top;
multiset<int> q[N];
multiset<int>::iterator it;

void add(int u, int v, int c) {
edge[++top] = (tt){path[u], v, c};
path[u] = top;
}
int dfs(int u, int c) {
vis[u] = 1;
if (q[u].size()) q[u].clear();
for (int i = path[u], l; i; i = edge[i].nxt)
if (!vis[edge[i].to]) {
l = dfs(edge[i].to, edge[i].dis);
if (l >= mid) ++cnt;
else q[u].insert(l);
}
int ans = 0;
while (!q[u].empty()) {
it = q[u].lower_bound(mid-(*q[u].begin()));
if (it == q[u].begin() && q[u].count(*q[u].begin()) == 1) ++it;
if (it != q[u].end()) ++cnt, q[u].erase(q[u].find(*it));
else ans = max(ans, *q[u].begin());
q[u].erase(q[u].find(*q[u].begin()));
}
return ans+c;
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i < n; i++) {
scanf("%d%d%d", &u, &v, &l);
}
int ans, R = inf, L = 0;
while (L <= R) {
mid = (L+R)>>1;
cnt = 0;
for (int i = 1; i <= n; i++) vis[i] = 0;
if  (dfs(1, 0) >= mid) ++cnt;
if (cnt >= m) ans = mid, L = mid+1;
else R = mid-1;
}
printf("%d\n", ans);
return 0;
}

Day2 T1 旅行

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
const int N = 5000+5;

int n, m, a[N], b[N], ku, kv, t, ans[N], kp[N], vis[N];
vector<int> to[N];

void update() {
if (ans[1] == 0) memcpy(ans, kp, sizeof(ans));
else for (int i = 1; i <= n; i++)
if (ans[i] != kp[i]) {
if (ans[i] > kp[i]) memcpy(ans, kp, sizeof(ans));
return;
}
}
bool dfs(int u, int fa) {
if (vis[u]) return false;
kp[++t] = u; vis[u] = 1;
for (int i = 0, sz = to[u].size(), v; i < sz; i++)
if ((v = to[u][i]) != fa && !(u == ku && v == kv || u == kv && v == ku))
if (!dfs(v, u)) return false;
return true;
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++) {
scanf("%d%d", &a[i], &b[i]);
to[a[i]].pb(b[i]), to[b[i]].pb(a[i]);
}
for (int i = 1; i <= n; i++) sort(to[i].begin(), to[i].end());
if (n == m+1) {dfs(1, 0); update(); }
else for (int i = 1; i <= m; i++) {
ku = a[i], kv = b[i]; t = 0;
memset(vis, 0, sizeof(vis));
if (dfs(1, 0) && t == n) update();
}
for (int i = 1; i <= n; i++) printf("%d%c", ans[i], " \n"[i == n]);
return 0;
}

Day2 T2 填数游戏

#include <bits/stdc++.h>
using namespace std;
const int N = 1000000+15, yzh = 1000000007;

int n, m, ans, s[N], a[N];

int main() {
scanf("%d%d", &n, &m);
if (n > m) swap(n, m);
if (n == 1) {
ans = 1;
for (int i = 1; i <= m; i++) ans = 2ll*ans%yzh;
} else if (n == 2) {
ans = 4;
for (int i = 1; i < m; i++) ans = 3ll*ans%yzh;
} else {
s[n+m] = 1;
for (int i = n+m-1; i >= 1; i--)
a[i] = 2+(i <= n)+(i <= m),
s[i] = 1ll*s[i+1]*a[i]%yzh;
(ans += 4ll*s[3]%yzh) %= yzh;
(ans += 4ll*(a[4]+1)*s[5]%yzh) %= yzh;
for (int i = 4; i <= n; i++) {
(ans += 2ll*(3+(i <= m))*(a[i+1]+1)*s[i+2]%yzh) %= yzh;
}
(ans += 2ll*(a[n+1]+1)*s[n+2]%yzh) %= yzh;
for (int i = 4; i <= m; i++) {
(ans += 2ll*(3+(i <= n))*(a[i+1]+1)*s[i+2]%yzh) %= yzh;
}
(ans += 2ll*(a[m+1]+1)*s[m+2]%yzh) %= yzh;
}
printf("%d\n", ans);
return 0;
}

Day2 T3 保卫王国

#include <bits/stdc++.h>
#define ll long long
#define min(a, b) ((a) < (b) ? (a) : (b))
using namespace std;
const int N = 100000+5;
const ll inf = 1e10+1;

char rubbish_bin[3];
int n, m, lim, p[N], u, v, path[N], top, x, y, fa[N][20], dep[N];
ll dp[N][2], f[N][20][2][2];
struct tt {
int to, nxt;
} edge[N<<1];

x = 0; char ch = getchar();
while (ch < '0' || ch > '9') ch = getchar();
while (ch >= '0' && ch <= '9') x = (x<<1)+(x<<3)+ch-48, ch = getchar();
}
void add(int u, int v) {
edge[++top] = (tt){v, path[u]};
path[u] = top;
}
void dfs(int u, int f, int d) {
dep[u] = d, fa[u][0] = f, dp[u][1] = p[u];
for (int i = 1; i <= lim; i++)
fa[u][i] = fa[fa[u][i-1]][i-1];
for (int i = path[u], v; i; i = edge[i].nxt)
if ((v = edge[i].to) != f) {
dfs(v, u, d+1);
dp[u][0] += dp[v][1];
dp[u][1] += min(dp[v][0], dp[v][1]);
}
}
ll cal(int u, int x, int v, int y) {
if (dep[u] < dep[v]) swap(u, v), swap(x, y);
ll u0, u1, v0, v1, t0, t1, l0, l1; int lca;
if (x) u1 = dp[u][1], u0 = inf;
else u1 = inf, u0 = dp[u][0];
if (y) v1 = dp[v][1], v0 = inf;
else v1 = inf, v0 = dp[v][0];
for (int i = lim; i >= 0; i--)
if (dep[fa[u][i]] >= dep[v]) {
t0 = u0, t1 = u1;
u0 = min(t0+f[u][i][0][0], t1+f[u][i][1][0]);
u1 = min(t0+f[u][i][0][1], t1+f[u][i][1][1]);
u = fa[u][i];
}
if (u == v) {
lca = u;
if (y) l0 = inf, l1 = u1;
else l0 = u0, l1 = inf;
} else {
for (int i = lim; i >= 0; i--)
if (fa[u][i] != fa[v][i]) {
t0 = u0, t1 = u1;
u0 = min(t0+f[u][i][0][0], t1+f[u][i][1][0]);
u1 = min(t0+f[u][i][0][1], t1+f[u][i][1][1]);
t0 = v0, t1 = v1;
v0 = min(t0+f[v][i][0][0], t1+f[v][i][1][0]);
v1 = min(t0+f[v][i][0][1], t1+f[v][i][1][1]);
u = fa[u][i], v = fa[v][i];
}
lca = fa[u][0];
l0 = dp[lca][0]-dp[u][1]-dp[v][1]+u1+v1;
l1 = dp[lca][1]-min(dp[u][0], dp[u][1])-min(dp[v][0], dp[v][1])+min(u0, u1)+min(v0, v1);
}
for (int i = lim; i >= 0; i--)
if (fa[lca][i]) {
t0 = l0, t1 = l1;
l0 = min(t0+f[lca][i][0][0], t1+f[lca][i][1][0]);
l1 = min(t0+f[lca][i][0][1], t1+f[lca][i][1][1]);
lca = fa[lca][i];
}
if (min(l0, l1) < inf) return min(l0, l1);
else return -1;
}
int main() {
for (int i = 1; i <= n; i++) read(p[i]);
for (int i = 1; i < n; i++) {
scanf("%d%d", &u, &v);
}
dfs(1, 0, 1);
for (int u = 1; u <= n; u++) {
f[u][0][0][0] = inf;
f[u][0][1][0] = dp[fa[u][0]][0]-dp[u][1];
f[u][0][0][1] = f[u][0][1][1] = dp[fa[u][0]][1]-min(dp[u][0], dp[u][1]);
}
for (int i = 1; i <= lim; i++)
for (int u = 1; u <= n; u++) {
int t = fa[u][i-1];
f[u][i][0][0] = min(f[u][i-1][0][0]+f[t][i-1][0][0], f[u][i-1][0][1]+f[t][i-1][1][0]);
f[u][i][0][1] = min(f[u][i-1][0][0]+f[t][i-1][0][1], f[u][i-1][0][1]+f[t][i-1][1][1]);
f[u][i][1][0] = min(f[u][i-1][1][0]+f[t][i-1][0][0], f[u][i-1][1][1]+f[t][i-1][1][0]);
f[u][i][1][1] = min(f[u][i-1][1][0]+f[t][i-1][0][1], f[u][i-1][1][1]+f[t][i-1][1][1]);
}
while (m--) {
}