【BZOJ 2594】【WC 2006】水管局长数据加强版
离线后倒过来做,这样就跟魔法森林差不多了,缩边为点就可以统计边的权值了。
1A真是爽,可惜常数炸上了天,这是滥用stl容器和无脑link,cut的后果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | #include<map> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 100003; const int M = 1000003; void read( int &k) { k = 0; int fh = 1; char c = getchar (); for (; c < '0' || c > '9' ; c = getchar ()) if (c == '-' ) fh = -1; for (; c >= '0' && c <= '9' ; c = getchar ()) k = (k << 1) + (k << 3) + c - '0' ; k = k * fh; } struct node *null; struct node { node *ch[2], *fa; int mx, mxid, d, id; short rev; bool pl() { return fa->ch[1] == this ;} bool check() { return fa == null || (fa->ch[0] != this && fa->ch[1] != this );} void push() { if (rev) {rev = 0; swap(ch[0], ch[1]); ch[0]->rev ^= 1; ch[1]->rev ^= 1;}} void count() { mxid = id; mx = d; if (ch[0]->mx > mx) {mx = ch[0]->mx; mxid = ch[0]->mxid;} if (ch[1]->mx > mx) {mx = ch[1]->mx; mxid = ch[1]->mxid;} } void setc(node *r, bool c) {ch[c] = r; r->fa = this ;} } pool[N + M]; struct Quee{ int op, u, v;} Q[N]; struct Data{ int u, v, e;} E[M]; struct maa{ int u, v; bool operator < ( const maa data) const { return u == data.u ? v < data.v : u < data.u;} }; bool cmp(Data A, Data B) { return A.e < B.e;} map <maa, int > ma; bool cannot[M]; namespace LCT { int fa[N]; int find( int x) { return fa[x] == x ? x : (fa[x] = find(fa[x]));} void rotate(node *r) { node *f = r->fa; bool c = r->pl(); if (f->check()) r->fa = f->fa; else f->fa->setc(r, f->pl()); f->setc(r->ch[!c], c); r->setc(f, !c); f->count(); } void update(node *r) { if (!r->check()) update(r->fa); r->push();} void splay(node *r) { update(r); for (; !r->check(); rotate(r)) if (!r->fa->check()) rotate(r->pl() == r->fa->pl() ? r->fa : r); r->count(); } node *access(node *r) {node *y = null; for (; r != null; y = r, r = r->fa) splay(r), r->ch[1] = y; return y;} void changert(node *r) {access(r)->rev ^= 1; splay(r);} void link(node *r, node *t) {changert(r); r->fa = t;} void cut(node *r, node *t) {changert(r); access(t); splay(t); t->ch[0]->fa = null; t->ch[0] = null;} node *findrt(node *r) {access(r); splay(r); while (r->ch[0] != null) r = r->ch[0]; return r;} void newnode( int k, int num) { pool[k].ch[0] = pool[k].ch[1] = pool[k].fa = null; pool[k].id = pool[k].mxid = k; pool[k].d = pool[k].mx = num; pool[k].rev = 0; } int A[N]; void Build( int n, int m, int q) { null = &pool[0]; null->ch[0] = null->ch[1] = null->fa = null; null->id = null->d = null->mx = null->mxid = null->rev = 0; int u, v, e; for ( int i = 1; i <= n; ++i) newnode(i, 0); for ( int i = 1; i <= m; ++i) { read(u); read(v); read(e); if (u > v) swap(u, v); E[i] = (Data) {u, v, e}; } sort(E + 1, E + m + 1, cmp); for ( int i = 1; i <= m; ++i) { ma[(maa) {E[i].u, E[i].v}] = i; newnode(i + n, E[i].e); } for ( int i = 1; i <= q; ++i) { read(Q[i].op); read(Q[i].u); read(Q[i].v); if (Q[i].u > Q[i].v) swap(Q[i].u, Q[i].v); if (Q[i].op == 2) cannot[ma[(maa) {Q[i].u, Q[i].v}]] = 1; } node *tox, *toy, *toe; int cnt = 0, x, y, fx, fy; for ( int i = 1; i <= n; ++i) fa[i] = i; for ( int i = 1; i <= m; ++i) { x = E[i].u; y = E[i].v; fx = find(x); fy = find(y); if (fx != fy && !cannot[e = ma[(maa) {x, y}]]) { ++cnt; fa[fx] = fy; tox = &pool[x]; toy = &pool[y]; toe = &pool[e + n]; link(tox, toe); link(toy, toe); if (cnt == n - 1) break ; } } cnt = 0; for ( int i = q; i >= 1; --i) { if (Q[i].op == 1) { tox = &pool[Q[i].u]; toy = &pool[Q[i].v]; changert(tox); access(toy); splay(toy); A[++cnt] = toy->mx; } else { tox = &pool[Q[i].u]; toy = &pool[Q[i].v]; e = ma[(maa) {Q[i].u, Q[i].v}]; changert(tox); access(toy); splay(toy); if (E[e].e < toy->mx) { u = toy->mxid - n; tox = &pool[E[u].u]; toy = &pool[E[u].v]; toe = &pool[u + n]; cut(tox, toe); cut(toy, toe); tox = &pool[Q[i].u]; toy = &pool[Q[i].v]; toe = &pool[e + n]; link(tox, toe); link(toy, toe); } } } for ( int i = cnt; i; --i) printf ( "%d\n" , A[i]); } } int n, m, q; int main() { read(n); read(m); read(q); LCT::Build(n, m, q); return 0; } |
模板一定不能写残啊,想起一个月前Round1Day1调LCT的模板调了4h,查出各种手残的错误QAQ然而并没有什么用。
NOI 2017 Bless All
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】凌霞软件回馈社区,携手博客园推出1Panel与Halo联合会员
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何统计不同电话号码的个数?—位图法
· C#高性能开发之类型系统:从 C# 7.0 到 C# 14 的类型系统演进全景
· 从零实现富文本编辑器#3-基于Delta的线性数据结构模型
· 记一次 .NET某旅行社酒店管理系统 卡死分析
· 长文讲解 MCP 和案例实战
· C#高性能开发之类型系统:从 C# 7.0 到 C# 14 的类型系统演进全景
· 管理100个小程序-很难吗
· 基于Blazor实现的运输信息管理系统
· 微信支付功能的设计实现与关键实践(UniApp+Java)全代码
· 用c#从头写一个AI agent,实现企业内部自然语言数据统计分析