"NOI2014" Get up difficulty syndrome
Greedy by bit
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #define MAXN 100010using namespace Std;int N, m;int Tp[maxn], v[maxn];int getans (int final, int p) {for (int i = 1; I <= n; i + +) {if (t P[i] = = 0) Final &= v[i];if (tp[i] = = 1) Final |= v[i];if (tp[i] = 2) final ^= v[i];} Return final >> P & 1;} BOOL Check (int x) {if (Getans (0, X) >= Getans (1 << x, x)) return 0;return 1; int solve (int final) {for (int i = 1; I <= n; i + +) {if (tp[i] = = 0) Final &= v[i];if (tp[i] = = 1) Final |= v[i];if (TP [I] = = 2) final ^= v[i];} return final;} int main () {scanf ("%d%d", &n, &m); char cmd[5]; int x;for (int i = 1; I <= n; i + +) {scanf ("%s%d", CMD, &x); if ( Cmd[0] = = ' A ') tp[i] = 0;if (cmd[0] = = ' O ') tp[i] = 1;if (cmd[0] = = ' X ') tp[i] = 2;v[i] = X;} int log = 1;for (; 1ll << log <= m; log + +); log--;int ans = 0;for (int i = log; I >= 0; I-) if (ans | (1 << i)) <= m && Check (i)) ans = ans | (1 << i);p rintf ("%d\n ", Solve (ans)); return 0;}
"NOI2014" Magical Forest
Minimum incremental Spanning tree
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <CMA Th> #define MAXN 200010 using namespace std; int n, m; struct edge_{int u, V, a, B; void Read () {scanf ("%d%d%d%d", &u, &v, &a, &b);} BOOL operator< (const edge_& k) const{return a < k.a; }}G[MAXN]; int L[MAXN], R[MAXN]; int VAL[MAXN], c[maxn][2], FA[MAXN], POS[MAXN]; BOOL REV[MAXN]; Namespace splay{#define L c[x][0] #define R C[x][1] int ST[MAXN], top; void Init () {memset (val, 0x80, sizeof Val); for (int i = 1; I <= 2 * n; i + +) pos[i] = i; } void Pushup (int x) {pos[x] = x; if (Val[pos[x]] < Val[pos[l]]) pos[x] = Pos[l]; if (Val[pos[x]] < Val[pos[r]]) pos[x] = Pos[r]; } void Pushdown (int x) {if (rev[x]) {rev[x] = 0; ReV[l] ^= 1; Rev[r] ^= 1; Swap (L, R); }} void rotate (int p, int x) {int mark = P = = C[x][1], y = c[p][mark ^ 1]; int z = fa[x]; if (x = = C[z][0]) c[z][0] = p; if (x = = C[z][1]) c[z][1] = p; if (y) fa[y] = x; FA[P] = Z; C[p][mark ^ 1] = x; FA[X] = p; C[x][mark] = y; Pushup (x); } bool IsRoot (int p) {return c[fa[p]][0]! = P && c[fa[p]][1]! = P; } void splay (int p) {st[top = 1] = p; for (int i = p;!isroot (i); i = Fa[i]) st[++ top] = Fa[i]; for (; top; top--) pushdown (St[top]); while (!isroot (p)) {int x = fa[p], y = fa[x]; if (IsRoot (x)) rotate (p, x); else if (p = = C[x][0] ^ x = = C[y][0]) rotate (p, x), rotate (p, y); else rotate (x, y), rotate (p, x); } pushup (P); }#undef l #undef r} namespace lct{void Access (int u) {int t = 0; while (U) {splay::splay (U); C[U][1] = t; t = u; U = fa[u]; }} void Evert (int u) {Access (U); Splay::splay (U); Rev[u] ^= 1; } void link (int u, int v, int t) {Evert (v); FA[V] = t; Evert (t); Fa[t] = u; } void Cut (int u, int v, int t) {Evert (t); Access (U); Splay::splay (U); C[u][0] = fa[t] = 0; Evert (t); Access (v); Splay::splay (v); C[v][0] = fa[t] = 0; } int find (int u) {Access (U); Splay::splay (U); while (c[u][0]) u = c[u][0]; return u; } int Ask (int u, int v) {if (Find (u)! = Find (v)) return-1; Evert (U); Access (v); Splay::splay (v); Return POS[V]; }} int main () {scanf ("%d%d", &n, &m); for (int i = 1; I <= m; i + +) G[i].read (); Sort (g + 1, G + 1 + m); Splay::init (); int ans = 0x7fffffff; int cnt = n; for (int i = 1; I <= m; i + +) {int t = lct::ask (g[i].u, G[I].V); if (t = =-1) {T = + + cnt; L[t] = g[i].u; R[t] = G[I].V; Val[t] = g[i].b; FA[T] = c[t][0] = c[t][1] = 0; Pos[t] = t; Lct::link (L[t], r[t], T); } else if (Val[t] > g[i].b) {lct::cut (l[t], r[t], T); L[t] = g[i].u; R[t] = G[I].V; Val[t] = g[i].b; FA[T] = c[t][0] = c[t][1] = 0; Pos[t] = t; Lct::link (L[t], r[t], T); } t = Lct::ask (1, N); if (t! =-1) ans = min (ans, val[t] + g[i].a); cout << ans << ' << val[t] <<"<< g[i].a <<" << g[i].b << Endl; } if (ans > 1000000) ans =-1; printf ("%d\n", ans); return 0; }
"NOI2014" zoo
Kmp
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define MAXN 1000010#define mod 1000000007llusing namespace Std;int nxt[maxn], N;char c[maxn];int p[maxn];long long ans;void Solve () {p [1] = 1;nxt[0] = nxt[1] = 0;for (int i = 2; I <= n; i + +) {int J = nxt[i-1];while (J && c[i]! = c[j + 1]) j = NXT [J];if (c[i] = = c[j + 1]) J ++;nxt[i] = j;p[i] = P[j] + 1;} Int J = 0;ans = 1;for (int i = 2; I <= n; i + +) {while (J && c[i]! = c[j + 1]) j = nxt[j];if (c[i] = = c[j + 1]) J + +; while (J * 2 > i) j = Nxt[j];ans = 1ll * (P[j] + 1) * ans% mod;} printf ("%lld\n", ans);} int main () {int test;scanf ("%d", &test), while (test--) {scanf ("%s", C + 1), n = strlen (c + 1); solve ();} return 0;}
"NOI2014" Random number generator
Get the sequence out and see if you can add it every time you take the minimum value.
Each line has a continuous range of desirable ranges, and maintaining Li and Ri can determine
#include <algorithm> #include <stdio.h>typedef long long ll;int x0, A, B, C, D;int N, M, Q;int t[25000001], mp[ 5001][5001];int l[5001], R[5001];int Rand () {x0 = (ll) A * x0 * x0% d + (LL) b * x0 + c)% D;return x0;} int main () {scanf ("%d%d%d%d%d", &x0, &a, &b, &c, &d); scanf ("%d%d%d", &n, &m, &q); int k = n * M;FOR (int i = 1; I <= K; i + +) t[i] = i;for (int i = 1; I <= K; i + +) Std::swap (T[i], t[rand ()% i + 1]); int X, y;for (int i = 1; I <= q; i + +) scanf ("%d%d", &x, &y), Std::swap (T[x], t[y]); int NW = 0;for (int i = 1; I & lt;= N; i + +) for (int j = 1; j <= M; j + +) Mp[i][j] = t[++ nw];for (int i = 1; I <= n; i + +) for (int j = 1; J &L t;= m; J + +) T[mp[i][j] = i << 16 | j;for (int i = 1; I <= n; i + +) l[i] = 1, r[i] = M;bool flag = false;for (int i = 1; I <= K; i + +) {x = T[i] >> ; 16;y = T[i] & 65535;if (l[x] <= y && y <= r[x]) {if (flag) Putchar ('); flag = true;printf ("%d", I); for (int j = 1; j < X; j + +) R[j] = Std::min (r[j], y); for (int j = x + 1; j <= N; j + +) L[j] = Std::max (l[j), Y );}} return 0;}
"NOI2014" Ticket purchase
Tree profile + three points
Long long took a long long to explode.
Change to Double.
Convex hull don't build wrong
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include < Vector> #define MAXN 200010using namespace Std;typedef long long ll;int n;struct edge{int to, Nxt;ll dis;} Edge[maxn];int H[MAXN], cnt;void Add (int u, int v, ll d) {edge[++ cnt] = (edge) {V, h[u], d};h[u] = cnt;} CONST LL inf = 1ll << 60;const int root = 1;ll P[MAXN], Q[MAXN], L[MAXN], DIS[MAXN], Dp[maxn];int FA[MAXN], ANC[MAXN ][20];int TOP[MAXN], SON[MAXN], POS[MAXN], SIZE[MAXN], dfs_clock;void dfs1 (int u) {size[u] = 1;for (int i = h[u]; i; i = EDG E[I].NXT) {int v = edge[i].to;if (v = = Fa[u]) continue;anc[v][0] = fa[v] = U;dis[v] = Dis[u] + EDGE[I].DIS;DFS1 (v); Size[u] + = Size[v];if (Size[v] > Size[son[u]]) son[u] = V;}} void dfs2 (int u, int tp) {Pos[u] = + + Dfs_clock;top[u] = tp;if (Son[u]) DFS2 (Son[u], TP); for (int i = h[u]; i; i = edge[i].nxt ) {int v = edge[i].to;if (v = = Fa[u] | | v = = son[u]) continue;dfs2 (V, v);}} int Find (int u, ll d) {for (int i = >=; I, 0; I-) if (diS[anc[u][i]] >= d) u = Anc[u][i];return u;} #define LC ID << 1#define RC ID << 1 | 1vector<int> t[maxn << 2];void update (int id, int l, int r, int u) {int top = t[id].size ()-1;while (Top > 0 ) {int T1 = T[id][top], t2 = t[id][top-1];if ((double) (Dp[u]-dp[t1])/(Dis[u]-dis[t1]) < (double) (Dp[u]-dp[t2]) /(Dis[u]-dis[t2])) Top--, t[id].pop_back (); Else break;} T[id].push_back (U); if (L = = r) Return;int mid = L + R >> 1;if (Pos[u] <= mid) Update (LC, L, Mid, u); else update (RC, M Id+1, R, u);} ll PD (int i, int u) {return dp[i] + (Dis[u]-dis[i]) * P[u] + q[u];} ll check (int id, int u) {int L = 0, r = t[id].size ()-1;LL ret = Inf;while (r-l >= 3) {int M1 = (L + L + R)/3, M2 = ( L + R + R)/3;if (PD (T[ID][M1], u) > pd (T[ID][M2], u)) L = m1;else r = m2;} for (int i = l; I <= R; i + +) ret = min (ret, PD (T[id][i], u)); return ret;} ll ask (int id, int l, int r, int l, int r, int u) {if (L = = L && r = = r) return check (ID, u); int mid = L + R >> 1;if (r <= Mid) return Ask (LC, L, Mid, L, R, U), if (L > Mid) return ask (RC, mid+1, R, L, R, u); return MIN (Ask (LC, L, Mid, L, Mid, U), ask (RC, mid+1, R, Mid+1, R, u));} ll query (int u) {ll d = dis[u]-l[u], ret = Inf;int NW = u; u = fa[u];while (u) {if (Dis[u] < D) Break;int L = Pos[top[u]], R = Pos[u];if (Dis[top[u]] < D) L = Pos[find (U, d)];ret = min (ret, ask (1, 1, N, L, R, NW)); u = Fa[top[u]];} return ret;} void solve (int u) {if (U! = 1) dp[u] = query (u); update (1, 1, N, u); for (int i = h[u]; i; i = edge[i].nxt) {int v = edge[i].to;i F (v = = Fa[u]) continue;solve (v);}} int main () {int test;scanf ("%d%d", &n, &test); int f; ll s;for (int i = 2; I <= n; i + +) {scanf ("%d%lld%lld%lld%lld ", &f, &s, &p[i], &q[i], &l[i]); Add (f, I, s);} DFS1 (Root);d fs2 (root, Root), for (int j = 1; 1 << j <= N; j + +) for (int i = 1; I <= n; i + +) anc[i][j] = Anc[a Nc[i][j-1]][j-1];solve (Root), for (int i = 2; I <= n; i + +) printf ("%lld\n", Dp[i]); return 0;}
[NOI 2014] record the title