Several problems
parent
e624bf1065
commit
aa21df1bd5
@ -0,0 +1,118 @@
|
||||
#include <cstdio>
|
||||
template <typename T>
|
||||
inline T min(const T &x, const T &y) { return x < y ? x : y; }
|
||||
template <typename T>
|
||||
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;
|
||||
}
|
||||
@ -0,0 +1,156 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
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<pair<int, int>, 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<int, int> 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;
|
||||
}
|
||||
@ -0,0 +1,130 @@
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <queue>
|
||||
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 <typename T>
|
||||
struct __ext_priority_queue
|
||||
{
|
||||
private:
|
||||
std::priority_queue<T> 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<int> 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<int, int> 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;
|
||||
}
|
||||
Loading…
Reference in new issue