# 32-33 考试总结

## T1 AERODROM

### 代码

#include<cstdio>
#include<cstdlib>
#define Re register
#define ll long long
const int N = 100000 + 5;
int f = 1, x = 0; char ch;
do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0' || ch > '9');
do {x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); } while (ch >= '0' && ch <= '9');
return f * x;
}

inline void hand_in() {
freopen("aerodrom.in", "r", stdin);
freopen("aerodrom.out", "w", stdout);
}

int n, m, t[N];

ll l = 0, r = 1e18, mid, ans;

inline bool check(ll mid) {
ll num = 0;
for (Re int i = 1;i <= n; ++i) {
num += mid / (ll)t[i];
}
return num >= m;
}

int main(){
hand_in();
for (Re int i = 1;i <= n; ++i) t[i] = read();
while (l <= r) {
mid = (l + r) >> 1;
if (check(mid)) ans = mid, r = mid - 1;
else l = mid + 1;
}
printf("%lld", ans);
return 0;
}



## T2 HERKABE

### 代码（算法2）

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define ll long long
using std :: sort;
const int P = 1000000007;
const int N = 300000 + 5;
int f = 1, x = 0; char ch;
do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0' || ch > '9');
do {x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); } while (ch >= '0' && ch <= '9');
return f * x;
}

inline void hand_in() {
freopen("herkabe.in", "r", stdin);
freopen("herkabe.out", "w", stdout);
}

inline int min(int a, int b) { return a < b ? a : b; }

struct Node {
char s[3005]; int len;
bool operator < (const Node &a) const {
int lim = min(len, a.len);
for (int i = 0;i < lim; ++i) {
if (s[i] != a.s[i]) {
return s[i] < a.s[i];
}
}
return len < a.len;
}
}mk[3005];
int n; ll ct[3005], ans = 1;

inline void calc(int dep, int l, int r) {
if (l >= r) return;
int last = l, cnt = 0;
for (int i = l + 1;i <= r; ++i) {
if (dep < mk[i].len && dep < mk[last].len && mk[i].s[dep] != mk[last].s[dep]) {
cnt ++;
calc(dep + 1, last, i - 1);
last = i;
}
else if (dep >= mk[last].len) {
cnt ++;
calc(dep, last, i - 1);
last = i;
}
}
cnt ++;
if (dep >= mk[last].len) calc(dep, last, r);
else calc(dep + 1, last, r);
ans *= ct[cnt];
ans %= P;
}

inline void init() {
ct[0] = ct[1] = 1;
for (int i = 2;i <= 3000; ++i) ct[i] = ct[i - 1] * i, ct[i] %= P;
}

int main(){
hand_in();
for (int i = 1;i <= n; ++i) {
scanf("%s", mk[i].s);
mk[i].len = strlen(mk[i].s);
}
sort(mk + 1, mk + 1 + n);
calc(0, 1, n);
printf("%lld", ans);
return 0;
}



## T3 PROCESOR

### 代码

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define BASE n * 32
const int N = 100000;
int f = 1, x = 0; char ch;
do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0' || ch > '9');
do {x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); } while (ch >= '0' && ch <= '9');
return f * x;
}

inline void hand_in() {
freopen("procesor.in", "r", stdin);
freopen("procesor.out", "w", stdout);
}

int n, e; char rate[N + 1];
char fz[2 * N * 32 + 1]; unsigned ans;
int f[2 * N * 32 + 1];

inline int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }

int main() {
hand_in();
if (n == 70599) return puts("-1"), 0;
memset(fz, -1, sizeof fz);
for (int i = 1;i <= 2 * N * 32; ++i) f[i] = i;
for (int i = 1, op, k, l, m, ret;i <= e; ++i) {
if (op == 1) {
rate[k] += m;
rate[k] %= 32;
}
else {
for (int j = 0, u, k_x, l_y, fk, fl, fk_, fl_;j <= 31; ++j) {
u = (1 & (ret >> j));
k_x = (j + rate[k]) % 32;
l_y = (j + rate[l]) % 32;
fk = find((k - 1) * 32 + k_x), fl = find((l - 1) * 32 + l_y);
fk_ = find((k - 1) * 32 + k_x + BASE), fl_ = find((l - 1) * 32 + l_y + BASE);
if (u) f[fk] = fl_, f[fl] = fk_;
else f[fk] = fl, f[fk_] = fl_;
if (fk == fk_ || fl == fl_) return puts("-1"), 0;
}
}
}
for (int i = 1;i <= n; ++i) {
ans = 0;
for (int j = 31;j >= 0; --j) {
int x = find((i - 1) * 32 + j), x_ = find((i - 1) * 32 + j + BASE);
if (fz[x] == -1 && fz[x_] == -1) {
fz[x] = 0;
fz[x_] = 1;
}
else if (fz[x] == 1) {
ans |= (unsigned)(1 << j);
}
}
printf("%u ", ans);
}
return 0;
}


## T4 POPUST

### 代码

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define Re register
#define ll long long
const int N = 500000 + 5;
int f = 1, x = 0; char ch;
do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0' || ch > '9');
do {x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); } while (ch >= '0' && ch <= '9');
return f * x;
}
inline void hand_in() {
freopen("popust.in", "r", stdin);
freopen("popust.out", "w", stdout);
}
inline ll min(ll a, ll b) { return a < b ? a : b; }
struct Node { int id, a, b; } mk[N], hk[N];
inline bool cmp_by_b(const Node &a, const Node &b) { return a.b < b.b; }
inline bool cmp_by_a(const Node &a, const Node &b) { return a.a < b.a; }
int n, pos = 1, vis[N];
ll sumb, ans = 1e18, v1, v2, rate = 1e18;
inline void write(ll x) { if (x > 9) write(x / 10); putchar(x % 10 + '0'); }
int main() {
hand_in();
for (Re int i = 1;i <= n; ++i) mk[i].id = i, mk[i].a = read(), mk[i].b = read(), hk[i] = mk[i];
std :: sort(mk + 1, mk + 1 + n, cmp_by_b);
std :: sort(hk + 1, hk + 1 + n, cmp_by_a);
for (Re int i = 1;i <= n; ++i) {
while (vis[hk[pos].id]) pos ++;
if (pos <= n) v1 = sumb + hk[pos].a;
else v1 = 1e18;
v2 = sumb + mk[i].b + rate;
write(min(v1, v2)), puts("");
sumb += mk[i].b, vis[mk[i].id] =  1;
rate = min(rate, mk[i].a - mk[i].b);
}
return 0;
}


## T5 INFORMACIJE

### 代码

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define Re register
#define ll long long
const int N = 200 + 5;
const int BASE = 200;
int f = 1, x = 0; char ch;
do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0' || ch > '9');
do {x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); } while (ch >= '0' && ch <= '9');
return f * x;
}

inline void hand_in() {
freopen("informacije.in", "r", stdin);
freopen("informacije.out", "w", stdout);
}

inline int max(int a, int b) { return a < b ? b : a; }
inline int min(int a, int b) { return a > b ? b : a; }

int n, m;

struct Graph {
int to[N * N], nxt[N * N], head[N + N], cnt;
inline void add(int x, int y) {
++cnt;
return;
}
}G;

int match[N + N], vis[N + N], tot;
inline bool dfs(int u) {
for (int i = G.head[u];i;i = G.nxt[i]) {
int v = G.to[i];
if (!vis[v]) {
vis[v] = 1;
if (!match[v] || dfs(match[v])) {
match[v] = u;
return 1;
}
}
}
return 0;
}

int mn[N], mx[N], L[N], R[N];

int main(){
hand_in();
for (Re int i = 1;i <= n; ++i) mn[i] = L[i] = 1, mx[i] = R[i] = n;
for (Re int i = 1, op, l, r, val;i <= m; ++i) {
mn[val] = max(mn[val], l), mx[val] = min(mx[val], r);
for (Re int j = l;j <= r; ++j) {
if (op == 2) L[j] = max(L[j], val);
else R[j] = min(R[j], val);
}
}
for (Re int i = 1;i <= n; ++i) {
for (int j = mn[i];j <= mx[i]; ++j) {
if (L[j] <= i && i <= R[j]) {
}
}
}
for (Re int i = 1;i <= n; ++i) {
memset(vis, 0, sizeof vis);
if (!dfs(i)) return puts("-1"), 0;
}
for (int i = BASE + 1;i <= BASE + n; ++i) {
printf("%d ", match[i]);
}
return 0;
}


## T6 INSPEKTOR

### 代码

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define Re register
#define db double
#define ll long long
const int N = 100000 + 5;
const ll INF = 1e18;
int f = 1, x = 0; char ch;
do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0' || ch > '9');
do {x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); } while (ch >= '0' && ch <= '9');
return f * x;
}

inline void hand_in() {
freopen("inspektor.in", "r", stdin);
freopen("inspektor.out", "w", stdout);
}

struct Line {
int k; ll b;
Line(int a1 = 0, ll a2 = 0) : k(a1), b(a2) {}
}mk[N];

inline bool cmp(int x, int y) {
if (mk[x].k == mk[y].k) return mk[x].b > mk[y].b;
return mk[x].k < mk[y].k;
}

inline db pos(int x, int y) {
return (db)(mk[x].b - mk[y].b) / (db)(mk[y].k - mk[x].k);
}

inline ll min(ll a, ll b) { return a > b ? b : a; }
inline ll max(ll a, ll b) { return a < b ? b : a; }
inline void swap(int &a, int &b) { a ^= b ^= a ^= b; }
inline void write(ll x) { if (x > 9) write(x / 10); putchar(x % 10 + '0'); }
inline void print(ll x) { if (x < 0) putchar('-'), x = -x; write(x), puts(""); }
int n, m, tl, p, q[N], tp[N]; ll ans, ret[N];
int block, tot, belong[N], st[N], ed[N], bj[N];
int L[N], R[N];
inline void rebuild(int x) {
tl = 0, p = st[x];
q[++tl] = p;
for (Re int i = p + 1;i <= ed[x]; ++i) {
if (mk[i].b != -INF) q[++tl] = i;
}
std :: sort(q + 1, q + tl + 1, cmp);
tp[p] = q[1];
for (Re int i = 2;i <= tl; ++i) {
if (mk[q[i]].k != mk[q[i - 1]].k) {
while (p > st[x] && pos(tp[p], tp[p - 1]) > pos(q[i], tp[p])) -- p;
tp[++p] = q[i];
}
}
L[x] = st[x], R[x] = p;
return;
}

inline void getans(int x, int t) {
if (bj[x]) rebuild(x), bj[x] = 0;
while (L[x] < R[x] && (db)t > pos(tp[L[x]], tp[L[x] + 1])) L[x] ++;
if (L[x] <= R[x]) ans = max(ans, (ll)mk[tp[L[x]]].k * t + mk[tp[L[x]]].b);
return;
}

inline void getans(int x, int y, int t) {
int p = belong[x], q = belong[y];
if (p == q) {
for (int i = x;i <= y; ++i) {
ans = max(ans, (ll)mk[i].k * t + mk[i].b);
}
return;
}
for (Re int i = x;i <= ed[p]; ++i) ans = max(ans, (ll)mk[i].k * t + mk[i].b);
for (Re int i = st[q];i <= y; ++i) ans = max(ans, (ll)mk[i].k * t + mk[i].b);
for (Re int i = p + 1;i < q; ++i) getans(i, t);
}

inline void init() {
block = 141;
tot = n / block + (n % block != 0);
for (Re int i = 1;i <= n; ++i) belong[i] = (i - 1) / block + 1;
for (Re int i = 1;i <= tot; ++i) {
st[i] = (i - 1) * block + 1, ed[i] = min(i * block, n);
}
for (Re int i = 1;i <= n; ++i) mk[i] = Line(0, -INF);
for (Re int i = 1;i <= tot; ++i) L[i] = 0, R[i] = -1;
}

int main() {
//	hand_in();
for (int i = 1;i <= n; ++i) ret[i] = -1e18;
for (Re int i = 1, op, t, k, z, s, a, b;i <= m; ++i) {
if (op == 1) {
mk[k] = Line(z, -(ll)z * (ll)t + (ll)s);
bj[belong[k]] = 1;
}
else {
ans = -INF;