# ICPC World Finals 2019 题解

## 【A】Azulejos

### 题解：

#include <cstdio>
#include <algorithm>
#include <set>

const int MN = 500005;

int N, Ans1[MN], Ans2[MN];
struct dat{ int p, h, id; dat() {} dat(int h, int id) : h(h), id(id) {} } a1[MN], a2[MN];
inline bool operator <(dat i, dat j) { return i.h == j.h ? i.id < j.id : i.h < j.h; }

std::set<dat> s1, s2;

int main() {
scanf("%d", &N);
for (int i = 1; i <= N; ++i) scanf("%d", &a1[i].p);
for (int i = 1; i <= N; ++i) scanf("%d", &a1[i].h);
for (int i = 1; i <= N; ++i) scanf("%d", &a2[i].p);
for (int i = 1; i <= N; ++i) scanf("%d", &a2[i].h);
for (int i = 1; i <= N; ++i) a1[i].id = a2[i].id = i;
std::sort(a1 + 1, a1 + N + 1, [](dat i, dat j) { return i.p < j.p; });
std::sort(a2 + 1, a2 + N + 1, [](dat i, dat j) { return i.p < j.p; });
int cnt = 0;
for (int i = 0; i <= N; ++i) {
if (a1[i].p != a1[i + 1].p || a2[i].p != a2[i + 1].p) {
if (s1.size() < s2.size()) {
for (auto j : s1) {
auto it = s2.lower_bound(dat(j.h, 1));
if (it != s2.begin()) {
--it, ++cnt;
Ans1[cnt] = j.id;
Ans2[cnt] = it->id;
s2.erase(it);
}
else return puts("impossible"), 0;
}
s1.clear();
}
else {
for (auto j : s2) {
auto it = s1.upper_bound(dat(j.h, N));
if (it != s1.end()) {
++cnt;
Ans2[cnt] = j.id;
Ans1[cnt] = it->id;
s1.erase(it);
}
else return puts("impossible"), 0;
}
s2.clear();
}
if (a1[i].p != a1[i + 1].p)
for (int j = i + 1; j <= N && a1[j].p == a1[i + 1].p; ++j)
s1.insert(a1[j]);
if (a2[i].p != a2[i + 1].p)
for (int j = i + 1; j <= N && a2[j].p == a2[i + 1].p; ++j)
s2.insert(a2[j]);
}
}
for (int i = 1; i <= N; ++i) printf("%d ", Ans1[i]); puts("");
for (int i = 1; i <= N; ++i) printf("%d ", Ans2[i]); puts("");
return 0;
}


## 【B】Beautiful Bridges

### 题解：

#include <cstdio>
#include <cmath>
#include <algorithm>

typedef long long LL;
const LL Inf = 0x3f3f3f3f3f3f3f3f;
const int MN = 10005;

inline LL MySqrt(LL x) {
LL y = sqrt(x);
while (y * y > x) --y;
while ((y + 1) * (y + 1) <= x) ++y;
return y;
}

int N;
LL H, Alpha, Beta;
LL px[MN], py[MN];
LL f[MN];

int main() {
scanf("%d%lld%lld%lld", &N, &H, &Alpha, &Beta);
for (int i = 1; i <= N; ++i) scanf("%lld%lld", &px[i], &py[i]);
f[1] = Alpha * (H - py[1]);
for (int i = 2; i <= N; ++i) {
f[i] = Inf;
LL Lb = px[i] - 2 * (H - py[i]), Rb = px[i];
for (int j = i - 1; j >= 1; --j) {
LL C1 = px[i] - px[j], C2 = H - py[j];
LL Sqrt = MySqrt(8 * C1 * C2);
LL MIN = px[i] - 2 * (C1 + C2) - Sqrt;
LL MAX = px[i] - 2 * (C1 + C2) + Sqrt;
if (px[i] - px[j] <= 2 * (H - py[j])) MAX = px[j];
Lb = std::max(Lb, MIN);
Rb = std::min(Rb, MAX);
if (Lb <= px[j] && px[j] <= Rb)
f[i] = std::min(f[i], f[j] + Alpha * (H - py[i]) + Beta * (px[i] - px[j]) * (px[i] - px[j]));
}
}
if (f[N] != Inf) printf("%lld\n", f[N]);
else puts("impossible");
return 0;
}


## 【D】Circular DNA

### 题解：

#include <cstdio>
#include <vector>

inline void getStr(int &Typ, int &Idt) {
char ch; Idt = 0;
while ((ch = getchar()) != 'e' && ch != 's') ;
Typ = ch == 's' ? 1 : -1, ch = getchar();
while (Idt = Idt * 10 + (ch ^ '0'), (ch = getchar()) >= '0' && ch <= '9') ;
}

const int MN = 1000005;
const int M = 1000000;

int N;
int Ty[MN], Id[MN], S[MN], Ans[MN];
std::vector<int> G[MN];

int main() {
scanf("%d", &N);
for (int i = 1; i <= N; ++i)
getStr(Ty[i], Id[i]),
G[Id[i]].push_back(i);
for (int id = 1; id <= M; ++id) {
int Sum = 0, Mn = 0;
for (auto i : G[id]) {
Sum += Ty[i];
S[i] = Sum;
if (Mn > Sum) Mn = Sum;
}
if (Sum) continue;
for (int i = 0; i < (int)G[id].size(); ++i) {
if (S[G[id][i]] == Mn) {
if (i < (int)G[id].size() - 1)
++Ans[G[id][i] + 1], --Ans[G[id][i + 1] + 1];
else {
++Ans[G[id][i] % N + 1], --Ans[G[id][0] + 1];
if (G[id][i] != N) ++Ans[1];
}
}
}
}
for (int i = 1; i <= N; ++i) Ans[i] += Ans[i - 1];
int Ai = 1, Av = Ans[1];
for (int i = 2; i <= N; ++i)
if (Ans[i] > Av) Ai = i, Av = Ans[i];
printf("%d %d\n", Ai, Av);
return 0;
}


### 题解：

#include <cstdio>
#include <algorithm>
#include <vector>

const int MN = 500005;

int N, M;
std::vector<int> G[MN];
int d[MN];

int vis[MN], que[MN], l, r;

int Ans, A1[MN], A2[MN];

int main() {
scanf("%d%d", &N, &M);
for (int i = 1; i <= M; ++i) {
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
++d[u], ++d[v];
}
for (int i = 1; i <= N; ++i)
std::sort(G[i].begin(), G[i].end());
l = 1, r = 0;
for (int i = 1; i <= N; ++i)
if (d[i] == 1) vis[i] = 1, que[++r] = i;
while (l <= r) {
int u = que[l++];
for (auto v : G[u]) {
if (!vis[v] && --d[v] == 1)
vis[v] = 1, que[++r] = v;
}
}
l = 1, r = 0;
for (int i = 1; i <= N; ++i) vis[i] = 0;
for (int i = 1; i <= N; ++i)
if (d[i] > 1) vis[i] = 1, que[++r] = i;
while (l <= r) {
int u = que[l++];
for (auto v : G[u]) {
if (!vis[v])
vis[v] = 1, que[++r] = v;
}
}
for (int u = 1; u <= N; ++u) {
for (auto v : G[u]) {
if (!vis[u] && G[u].size() == 1)
A1[++Ans] = u, A2[Ans] = v;
if (vis[u] && d[u] > 1 && d[v] == 1)
A1[++Ans] = u, A2[Ans] = v;
}
}
printf("%d\n", Ans);
for (int i = 1; i <= Ans; ++i)
printf("%d %d\n", A1[i], A2[i]);
return 0;
}


## 【G】First of Her Name

### 题解：

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>

const int MN = 1000005;

int N, Q;
int h[MN], nxt[MN], to[MN], w[MN], tot;
inline void Ins(int x, int y, int z) {
nxt[++tot] = h[x], to[tot] = y, w[tot] = z, h[x] = tot;
}

char str[MN];
int ch[MN][26], fail[MN], cnt;
inline int Insert(char *str) {
int now = 0;
for (int i = 0; str[i]; ++i) {
int c = str[i] - 'A';
if (!ch[now][c]) ch[now][c] = ++cnt;
now = ch[now][c];
} return now;
}

std::vector<int> G[MN];
int que[MN], l, r;
void BuildAC() {
fail[0] = -1;
que[l = r = 1] = 0;
while (l <= r) {
int u = que[l++];
for (int j = 0; j < 26; ++j) {
if (ch[u][j]) {
int to = fail[u];
while (~to && !ch[to][j]) to = fail[to];
fail[ch[u][j]] = ~to ? ch[to][j] : 0;
que[++r] = ch[u][j];
}
else ch[u][j] = ~fail[u] ? ch[fail[u]][j] : 0;
}
}
for (int i = 1; i <= cnt; ++i) G[fail[i]].push_back(i);
}

int ldf[MN], rdf[MN], dfc;
void DFS0(int u) {
ldf[u] = ++dfc;
for (auto v : G[u]) DFS0(v);
rdf[u] = dfc;
}

int b[MN];
inline void Mdf(int i) { for (; i <= dfc; i += i & -i) ++b[i]; }
inline int Qur(int i) { int a = 0; for (; i; i -= i & -i) a += b[i]; return a; }
void Solve(int u, int now) {
Mdf(ldf[now]);
for (int i = h[u]; i; i = nxt[i])
Solve(to[i], ch[now][w[i]]);
}

int Pos[MN];

int main() {
scanf("%d%d", &N, &Q);
for (int i = 1; i <= N; ++i) {
int f; char ch[3];
scanf("%s%d", ch, &f);
Ins(f, i, *ch - 'A');
}
for (int i = 1; i <= Q; ++i) {
scanf("%s", str);
std::reverse(str, str + strlen(str));
Pos[i] = Insert(str);
}
BuildAC();
DFS0(0);
Solve(0, 0);
for (int i = 1; i <= Q; ++i)
printf("%d\n", Qur(rdf[Pos[i]]) - Qur(ldf[Pos[i]] - 1));
return 0;
}


## 【H】Hobson's Trains

### 题解：

#include <cstdio>
#include <vector>

const int MN = 500005;

int N, K, d[MN];
int inc[MN], vis[MN], ist[MN], stk[MN], tp;

int cid, Len[MN], Id[MN];
std::vector<int> C[MN], sum[MN];

void Circ(int u) {
stk[++tp] = u, vis[u] = tp, ist[u] = 1;
if (!vis[d[u]]) Circ(d[u]);
else if (ist[d[u]]) {
++cid;
for (int i = vis[d[u]]; i <= tp; ++i)
C[cid].push_back(stk[i]),
inc[stk[i]] = cid,
Id[stk[i]] = (int)C[cid].size() - 1;
Len[cid] = C[cid].size();
sum[cid].resize(Len[cid]);
}
--tp, ist[u] = 0;
}

std::vector<int> G[MN];
int tc[MN], dep[MN], S[MN];

void DFS(int u) {
stk[++tp] = u, dep[u] = tp;
tc[u] = tc[d[u]];
++S[u];
if (tp > K + 1) --S[stk[tp - K - 1]];
for (auto v : G[u]) DFS(v), S[u] += S[v];
--tp;
}

int main() {
scanf("%d%d", &N, &K);
for (int i = 1; i <= N; ++i) scanf("%d", &d[i]);
for (int i = 1; i <= N; ++i) if (!vis[i]) Circ(i);
for (int i = 1; i <= N; ++i) if (!inc[d[i]]) G[d[i]].push_back(i);
for (int i = 1; i <= N; ++i) if (inc[i]) tc[i] = i;
for (int i = 1; i <= N; ++i) if (!inc[i] && inc[d[i]]) DFS(i);
for (int i = 1; i <= N; ++i) {
if (dep[i] > K) continue;
if (K - dep[i] + 1 >= Len[inc[tc[i]]])
++sum[inc[tc[i]]][0];
else {
++sum[inc[tc[i]]][Id[tc[i]]];
int ed = (Id[tc[i]] + K - dep[i] + 1) % Len[inc[tc[i]]];
--sum[inc[tc[i]]][ed];
if (ed < Id[tc[i]]) ++sum[inc[tc[i]]][0];
}
}
for (int id = 1; id <= cid; ++id) {
S[C[id][0]] = sum[id][0];
for (int i = 1; i < Len[id]; ++i)
sum[id][i] += sum[id][i - 1],
S[C[id][i]] = sum[id][i];
}
for (int i = 1; i <= N; ++i) printf("%d\n", S[i]);
return 0;
}


## 【K】Traffic Blights

posted @ 2019-04-05 15:51  粉兔  阅读(1337)  评论(2编辑  收藏