From aa21df1bd5990cc10ff13382ad1f970a142324a2 Mon Sep 17 00:00:00 2001 From: TooYoungTooSimp <6648049+TooYoungTooSimp@users.noreply.github.com> Date: Tue, 11 Apr 2017 07:58:09 +0800 Subject: [PATCH] Several problems --- OnlineJudges/lydsy/2002.cpp | 118 +++++++++++++++++++++++++ OnlineJudges/lydsy/2816.cpp | 156 ++++++++++++++++++++++++++++++++++ OnlineJudges/lydsy/4538.cpp | 130 ++++++++++++++++++++++++++++ 省选准备/HNOI2016/network.cpp | 30 ------- 4 files changed, 404 insertions(+), 30 deletions(-) create mode 100644 OnlineJudges/lydsy/2002.cpp create mode 100644 OnlineJudges/lydsy/2816.cpp create mode 100644 OnlineJudges/lydsy/4538.cpp diff --git a/OnlineJudges/lydsy/2002.cpp b/OnlineJudges/lydsy/2002.cpp new file mode 100644 index 0000000..fddb5ab --- /dev/null +++ b/OnlineJudges/lydsy/2002.cpp @@ -0,0 +1,118 @@ +#include +template +inline T min(const T &x, const T &y) { return x < y ? x : y; } +template +inline void swap(T &x, T &y) +{ + T t = x; + x = y; + y = t; +} +int K[200020]; +struct node +{ + int sz; + bool rev; + node *ch[2], *fa; + int dir() { return this == 0 || this->fa == 0 ? -1 : this == this->fa->ch[1]; } + bool isRoot() { return this->fa == 0 || (this != this->fa->ch[0] && this != this->fa->ch[1]); } +} T[200020]; +inline void update(node *x) +{ + x->sz = 1; + if (x->ch[0]) x->sz += x->ch[0]->sz; + if (x->ch[1]) x->sz += x->ch[1]->sz; +} +inline void push_down(node *x) +{ + if (x->rev) + { + swap(x->ch[0], x->ch[1]); + if (x->ch[0]) x->ch[0]->rev ^= 1; + if (x->ch[1]) x->ch[1]->rev ^= 1; + x->rev = false; + } +} +void push_down_rec(node *x) +{ + if (!x->isRoot()) push_down_rec(x->fa); + push_down(x); +} +inline void liftup(node *x) +{ + if (x == 0 || x->isRoot()) return; + int d = x->dir(); + node *f = x->fa, *ff = f->fa, *c = x->ch[d ^ 1]; + if (!f->isRoot()) ff->ch[f->dir()] = x; + x->fa = ff, f->fa = x, x->ch[d ^ 1] = f, f->ch[d] = c; + if (c) c->fa = f; + update(f), update(x); +} +inline void splay(node *x) +{ + push_down_rec(x); + for (; !x->isRoot(); liftup(x)) + if (!x->fa->isRoot()) + liftup(x->dir() ^ x->fa->dir() ? x : x->fa); + update(x); +} +inline void access(node *x) +{ + for (node *y = 0; x; y = x, x = x->fa) + { + splay(x), x->ch[1] = y; + if (y) y->fa = x; + } +} +inline void makeRoot(node *x) +{ + access(x), splay(x), x->rev ^= 1; +} +inline node *findRoot(node *x) +{ + access(x), splay(x); + while (push_down(x), x->ch[0]) x = x->ch[0]; + return splay(x), x; +} +inline void Link(node *x, node *f) +{ + makeRoot(x), x->fa = f; +} +inline void Cut(node *x, node *y) +{ + makeRoot(x), access(y), splay(y); + x->fa = y->ch[0] = 0; +} +inline node *Select(node *x, node *y) +{ + return makeRoot(x), findRoot(y); +} +int main() +{ + int n, m, op; + scanf("%d", &n); + for (int i = 0; i < n; i++) scanf("%d", K + i); + for (int i = 0; i < n; i++) Link(&T[i], &T[min(i + K[i], n)]); + scanf("%d", &m); + while (m--) + { + scanf("%d", &op); + if (op == 1) + { + int x; + scanf("%d", &x); + makeRoot(&T[n]); + access(&T[x]), splay(&T[x]); + printf("%d\n", T[x].ch[0] ? T[x].ch[0]->sz : 0); + } + if (op == 2) + { + int x, y; + scanf("%d%d", &x, &y); + Cut(&T[x], &T[min(x + K[x], n)]); + K[x] = y; + Link(&T[x], &T[min(x + K[x], n)]); + } + } + return 0; +} \ No newline at end of file diff --git a/OnlineJudges/lydsy/2816.cpp b/OnlineJudges/lydsy/2816.cpp new file mode 100644 index 0000000..122513d --- /dev/null +++ b/OnlineJudges/lydsy/2816.cpp @@ -0,0 +1,156 @@ +#include +#include +#include +#include +using namespace std; +struct node +{ + int val, max; + bool rev; + node *ch[2], *fa; + bool isRoot() { return this->fa == 0 || (this != this->fa->ch[0] && this != this->fa->ch[1]); } + int dir() { return this == 0 || this->isRoot() ? -1 : this == this->fa->ch[1]; } +} T[12][10010]; +inline void update(node *x) +{ + x->max = x->val; + if (x->ch[0]) x->max = max(x->max, x->ch[0]->max); + if (x->ch[1]) x->max = max(x->max, x->ch[1]->max); +} +inline void push_down(node *x) +{ + if (x->rev) + { + swap(x->ch[0], x->ch[1]); + if (x->ch[0]) x->ch[0]->rev ^= 1; + if (x->ch[1]) x->ch[1]->rev ^= 1; + x->rev = false; + } +} +void push_down_rec(node *x) +{ + if (!x->isRoot()) push_down_rec(x->fa); + push_down(x); +} +inline void liftup(node *x) +{ + if (x == 0 || x->isRoot()) return; + int d = x->dir(); + node *f = x->fa, *ff = f->fa, *c = x->ch[d ^ 1]; + if (!f->isRoot()) ff->ch[f->dir()] = x; + x->fa = ff, f->fa = x, x->ch[d ^ 1] = f, f->ch[d] = c; + if (c) c->fa = f; + update(f), update(x); +} +inline void splay(node *x) +{ + push_down_rec(x); + for (; !x->isRoot(); liftup(x)) + if (x->fa->isRoot()) + liftup(x->dir() ^ x->fa->dir() ? x : x->fa); + update(x); +} +inline void access(node *x) +{ + for (node *y = 0; x; y = x, x = x->fa) + { + splay(x), x->ch[1] = y; + if (y) y->fa = x; + } +} +inline void makeRoot(node *x) +{ + access(x), splay(x); + x->rev ^= 1; +} +inline node *findRoot(node *x) +{ + access(x), splay(x); + while (push_down(x), x->ch[0]) x = x->ch[0]; + return splay(x), x; +} +inline void Link(node *x, node *f) +{ + makeRoot(x), x->fa = f; +} +inline void Cut(node *x, node *y) +{ + makeRoot(x), access(y), splay(y); + x->fa = y->ch[0] = 0; +} +inline node *Select(node *x, node *y) +{ + return makeRoot(x), findRoot(y); +} +inline void Change(node *x, int v) +{ + access(x), splay(x); + x->val = v; + update(x); +} +map, int> col; +int sum[10001][12]; +int main() +{ + int n, m, c, k; + scanf("%d%d%d%d", &n, &m, &c, &k); + for (int i = 1, v; i <= n; i++) + { + scanf("%d", &v); + for (int j = 0; j < c; j++) T[j][i].val = T[j][i].max = v; + } + for (int i = 1, u, v, w; i <= m; i++) + { + scanf("%d%d%d", &u, &v, &w); + if (u > v) swap(u, v); + col[make_pair(u, v)] = w; + sum[u][w]++, sum[v][w]++; + Link(&T[w][u], &T[w][v]); + } + for (int i = 1, op; i <= k; i++) + { + scanf("%d", &op); + if (op == 0) + { + int x, v; + scanf("%d%d", &x, &v); + for (int j = 0; j < c; j++) + Change(&T[j][x], v); + } + if (op == 1) + { + int u, v, w; + scanf("%d%d%d", &u, &v, &w); + if (u > v) swap(u, v); + pair p = make_pair(u, v); + if (col.count(p) == 0) + puts("No such edge."); + else if (col[p] == w) + puts("Success."); + else if (sum[u][w] >= 2 || sum[v][w] >= 2) + puts("Error 1."); + else if (findRoot(&T[w][u]) == findRoot(&T[w][v])) + puts("Error 2."); + else + { + int ow = col[p]; + col[p] = w; + Cut(&T[ow][u], &T[ow][v]); + Link(&T[w][u], &T[w][v]); + sum[u][w]++, sum[v][w]++; + sum[u][ow]--, sum[v][ow]--; + puts("Success."); + } + } + if (op == 2) + { + int w, u, v; + scanf("%d%d%d", &w, &u, &v); + if (findRoot(&T[w][u]) != findRoot(&T[w][v])) + puts("-1"); + else + printf("%d\n", Select(&T[w][u], &T[w][v])->max); + } + } + return 0; +} \ No newline at end of file diff --git a/OnlineJudges/lydsy/4538.cpp b/OnlineJudges/lydsy/4538.cpp new file mode 100644 index 0000000..6ea78c2 --- /dev/null +++ b/OnlineJudges/lydsy/4538.cpp @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include +inline void read(int &x) +{ + int ch = x = 0, flag = 1; + while (!isdigit(ch = getchar())) + if (ch == '-') flag = -1; + for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0'; + x *= flag; +} +const int inf = 0x3f3f3f3f, N = int(1e5 + 5), M = N << 1; +#define avg(x, y) ((x) + (((y) - (x)) >> 1)) +#define L(x) ((x) << 1) +#define R(x) ((x) << 1 | 1) +template +struct __ext_priority_queue +{ +private: + std::priority_queue a, b; + +public: + void push(const T &x) { a.push(x); } + void pop(const T &x) { b.push(x); } + T top() + { + while (!b.empty() && a.top() == b.top()) a.pop(), b.pop(); + return a.empty() ? -1 : a.top(); + } +}; +__ext_priority_queue node[N << 2]; +void modify(int k, int l, int r, int x, int y, int v, bool t) +{ + if (x <= l && r <= y) return void(t ? node[k].push(v) : node[k].pop(v)); + int m = avg(l, r); + if (x < m) modify(L(k), l, m, x, y, v, t); + if (y > m) modify(R(k), m, r, x, y, v, t); +} +int query(int k, int l, int r, int p) +{ + int cur = node[k].top(); + if (l == r - 1) return cur; + int m = avg(l, r); + return std::max(cur, p < m ? query(L(k), l, m, p) : query(R(k), m, r, p)); +} +int adj[N], nxt[N << 1], to[N << 1], ecnt; +inline void addEdge(int f, int t) +{ + ecnt++; + nxt[ecnt] = adj[f]; + adj[f] = ecnt; + to[ecnt] = t; +} +int n, m; +int sz[N], fa[N], dep[N], son[N], top[N], idx[N], pos[N]; +void HLD() +{ + int u, v, len = 0; + static int que[N]; + que[len++] = 1; + for (int i = 0; i < len; i++) + { + sz[u = que[i]] = 1; + for (int e = adj[u]; e; e = nxt[e]) + if ((v = to[e]) != fa[u]) + fa[v] = u, dep[v] = dep[u] + 1, que[len++] = v; + } + for (int i = len - 1; i; i--) + { + u = que[i], v = fa[u]; + sz[v] += sz[u]; + if (sz[u] > sz[son[v]]) son[v] = u; + } + for (int i = 0, tot = 0; i < len; i++) + if (top[u = que[i]] == 0) + for (v = u; v; v = son[v]) + top[idx[pos[v] = tot++] = v] = u; +} +void work(int u, int v, int w, bool t) +{ + typedef std::pair seg; + static seg segs[N]; + int scnt = 0; + segs[scnt++] = seg(-1, -1); + while (top[u] != top[v]) + { + if (dep[top[u]] < dep[top[v]]) std::swap(u, v); + segs[scnt++] = seg(pos[top[u]], pos[u]); + u = fa[top[u]]; + } + if (dep[u] > dep[v]) std::swap(u, v); + segs[scnt++] = seg(pos[u], pos[v]); + segs[scnt] = seg(n, n); + std::sort(segs, segs + scnt); + for (int i = 0; i <= scnt; i++) + if (segs[i].second + 1 < segs[i + 1].first) + modify(1, 0, n, segs[i].second + 1, segs[i + 1].first, w, t); +} +int main() +{ + read(n), read(m); + for (int i = 1, u, v; i < n; i++) read(u), read(v), addEdge(u, v), addEdge(v, u); + HLD(); + for (int i = 1; i <= m; i++) + { + static int Qf[M], Qt[M], Qv[M]; + int type; + read(type); + if (type == 0) + { + read(Qf[i]), read(Qt[i]), read(Qv[i]); + work(Qf[i], Qt[i], Qv[i], true); + } + if (type == 1) + { + int t; + read(t); + work(Qf[t], Qt[t], Qv[t], false); + } + if (type == 2) + { + int x; + read(x); + printf("%d\n", query(1, 0, n, pos[x])); + } + } + return 0; +} diff --git a/省选准备/HNOI2016/network.cpp b/省选准备/HNOI2016/network.cpp index 59a24fd..6ea78c2 100644 --- a/省选准备/HNOI2016/network.cpp +++ b/省选准备/HNOI2016/network.cpp @@ -38,21 +38,6 @@ void modify(int k, int l, int r, int x, int y, int v, bool t) if (x < m) modify(L(k), l, m, x, y, v, t); if (y > m) modify(R(k), m, r, x, y, v, t); } -/* -void change(int x, int L, int R, int l, int r, int w, bool flag) -{ - if (L == l && R == r) - if (flag) t[x].insert(w); - else t[x].erase(w); - else - { - int mid = (L + R) >> 1; - if (r <= mid) change(x << 1, L, mid, l, r, w, flag); - else if (l > mid) change(x << 1 | 1, mid + 1, R, l, r, w, flag); - else change(x << 1, L, mid, l, mid, w, flag), change(x << 1 | 1, mid + 1, R, mid + 1, r, w, flag); - } -} -*/ int query(int k, int l, int r, int p) { int cur = node[k].top(); @@ -60,21 +45,6 @@ int query(int k, int l, int r, int p) int m = avg(l, r); return std::max(cur, p < m ? query(L(k), l, m, p) : query(R(k), m, r, p)); } -/* -void getmax(int x, int l, int r, int k) -{ - ans = max(ans, t[x].top()); - if (l == r) return; - else - { - int mid = (l + r) >> 1; - if (k <= mid) - getmax(x << 1, l, mid, k); - else - getmax(x << 1 | 1, mid + 1, r, k); - } -} -*/ int adj[N], nxt[N << 1], to[N << 1], ecnt; inline void addEdge(int f, int t) {