1 solutions
-
0
C++ :
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <cmath> using namespace std; const int BufferSize = 1 << 16; char buffer[BufferSize]; char *head = buffer + BufferSize; const char *tail = head; #ifndef ONLINE_JUDGE # define nextChar getchar #else inline char nextChar() { if (head == tail) { fread(buffer, 1, BufferSize, stdin); head = buffer; } return *head++; } #endif inline int getint() { static char c; while ((c = nextChar()) < '0' || c > '9'); int res = c - '0'; while ((c = nextChar()) >= '0' && c <= '9') res = res * 10 + c - '0'; return res; } namespace output { const int BufferSize = 1 << 21; char buffer[BufferSize + 1]; char *tail = buffer; char s[7]; inline void putint(int x) { if (!x) *tail++ = '0'; else { char *t = s; while (x > 0) *t++ = x % 10 + '0', x /= 10; while (t-- != s) *tail++ = *t; } *tail++ = '\n'; } inline void final() { fwrite(buffer, 1, tail - buffer, stdout); } } using output::putint; using output::final; const int MaxN = 100005; const int MaxM = MaxN * 2; int n, m, nQ = 0; struct lct_node { lct_node *lc, *rc, *fa; int sum; bool up, w; inline void update() { sum = up = w; if (lc) sum += lc->sum, up = lc->up; if (rc) sum += rc->sum; } inline bool is_root() { return !fa || (fa->lc != this && fa->rc != this); } inline void rotate() { lct_node *x = this, *y = fa, *z = y->fa; lct_node *b = x == y->lc ? x->rc : x->lc; x->fa = z, y->fa = x; if (b) b->fa = y; if (z) { if (z->lc == y) z->lc = x; else if (z->rc == y) z->rc = x; } if (x == y->lc) x->rc = y, y->lc = b; else x->lc = y, y->rc = b; y->update(); } inline void splay() { while (!is_root()) { if (!fa->is_root()) { if ((fa->lc == this) == (fa->fa->lc == fa)) fa->rotate(); else rotate(); } rotate(); } update(); } inline void access() { for (lct_node *p = this, *q = NULL; p; q = p, p = p->fa) { p->splay(), p->rc = q; p->update(); } } }; lct_node lct[MaxM]; inline void lct_link(int u, int v) { lct_node *x = lct + u; lct_node *y = lct + v; x->splay(), x->fa = y; } inline void lct_cut(int u) { lct_node *x = lct + u; x->access(), x->splay(); x->lc->fa = NULL, x->lc = NULL; x->update(); } inline void lct_modify(int u, bool w) { lct_node *x = lct + u; x->w = w, x->update(); } inline int lct_query(int u, int v) { int res = 0, edge = 1; lct_node *x = lct + u; lct_node *y = lct + v; x->access(), y->access(), x->splay(); x->fa ? res += x->sum, edge &= x->up : 0; x->access(), y->splay(); y->fa ? res += y->sum, edge &= y->up : 0; edge ? 0 : res += 2; return res; } struct halfEdge { int v; halfEdge *next; }; halfEdge adj_pool[MaxM * 2], *adj_tail = adj_pool; halfEdge *add[MaxN], *del[MaxN], *query[MaxN]; inline void addEdge(halfEdge *&adj, int v) { adj_tail->v = v, adj_tail->next = adj; adj = adj_tail++; } int vertex_n = 1, ver_n = 2; int vertex[MaxM]; int ver_l[MaxM], ver_r[MaxM]; int fa[MaxM]; int qu[MaxM], qv[MaxM]; int outcome[MaxM]; int main() { n = getint(), m = getint(); vertex[1] = ver_l[1] = 1, ver_r[1] = n; while (m--) { int type = getint(); if (type == 0) { vertex[++vertex_n] = ++ver_n; ver_l[vertex_n] = getint(); ver_r[vertex_n] = getint(); } else if (type == 1) { int l = getint(), r = getint(), v = getint(); l = max(l, ver_l[v]); r = min(r, ver_r[v]); if (l <= r) { fa[++ver_n] = vertex[v]; addEdge(add[l], ver_n); addEdge(del[r], ver_n); } } else { int x = getint(); addEdge(query[x], ++nQ); qu[nQ] = vertex[getint()]; qv[nQ] = vertex[getint()]; } } for (int u = 2; u <= ver_n; ++u) lct[u].fa = lct + u - 1; lct_modify(2, 1); for (int i = 1; i <= n; ++i) { for (halfEdge *e = add[i]; e; e = e->next) { lct_cut(e->v), lct_modify(e->v, 1); lct_link(e->v, fa[e->v]); } for (halfEdge *e = query[i]; e; e = e->next) outcome[e->v] = lct_query(qu[e->v], qv[e->v]); for (halfEdge *e = del[i]; e; e = e->next) { lct_cut(e->v), lct_modify(e->v, 0); lct_link(e->v, e->v - 1); } } for (int i = 1; i <= nQ; ++i) putint(outcome[i]); final(); return 0; }
- 1
Information
- ID
- 18814
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- (None)
- Tags
- # Submissions
- 0
- Accepted
- 0
- Uploaded By