【BZOJ 2594】【WC 2006】水管局长数据加强版

离线后倒过来做,这样就跟魔法森林差不多了,缩边为点就可以统计边的权值了。

1A真是爽,可惜常数炸上了天,这是滥用stl容器和无脑link,cut的后果

#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然而并没有什么用。

时间: 2024-08-05 08:04:12

【BZOJ 2594】【WC 2006】水管局长数据加强版的相关文章

【BZOJ 2594】 [Wc2006]水管局长数据加强版

2594: [Wc2006]水管局长数据加强版 Time Limit: 25 Sec  Memory Limit: 128 MB Submit: 1138  Solved: 364 [Submit][Status] Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一条从A至B的水管的路径,接着通过信息化的控制中心通知路径上的水管进入准备送水状态,等

bzoj 2594: [Wc2006]水管局长数据加强版 动态树

2594: [Wc2006]水管局长数据加强版 Time Limit: 25 Sec  Memory Limit: 128 MBSubmit: 934  Solved: 291[Submit][Status] Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一条从A至B的水管的路径,接着通过信息化的控制中心通知路径上的水管进入准备送水状态,等到路径

[bzoj2594][Wc2006]水管局长数据加强版

论蒟蒻的自我修养T_T.. 和noi2014魔法森林基本一样...然而数据范围大得sxbk...100w你告诉我(n+m)log(n+m)可过?[掀桌] 蒟蒻又蠢了..复杂度应该是O((n+q)log(n+m))吧.. 一开始数组开太小re了两发(要开到maxn+maxm),然后又开太大mle一发,然后无限tle...把记录类型全改成数组还是tle.... 最后把非lct部分改得和黄学长全部一样终于20+s卡过去了......... 然后发现自己原来是有个地方写萎了..一开始把没被删的边做kru

数据结构(动态树):COGS 27. [WC 2006] 水管局长

27. [WC 2006] 水管局长 ★★★☆   输入文件:tube.in   输出文件:tube.out   简单对比时间限制:3 s   内存限制:128 MB [问题描述 ] SC 省 MY 市有着庞大的地下水管网络,嘟嘟是 MY 市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从 x 处运往 y 处,嘟嘟需要为供水公司找到一条从 A 至 B 的水管的路径,接着通过信息化的控制中心通知路径上的水管进入准备送水状态,等到路径上每一条水管都准备好了,

BZOJ 2594: [Wc2006]水管局长数据加强版(kruskal + LCT)

Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一条从A至B的水管的路径,接着通过信息化的控制中心通知路径上的水管进入准备送水状态,等到路径上每一条水管都准备好了,供水公司就可以开始送水了.嘟嘟一次只能处理一项送水任务,等到当前的送水任务完成了,才能处理下一项. 在处理每项送水任务之前,路径上的水管都要进行一系列的准备操作,如清洗.消毒等等.嘟嘟在

BZOJ2594水管局长数据加强版

Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一条从A至B的水管的路径,接着通过信息化的控制中心通知路径上的水管进入准备送水状态,等到路径上每一条水管都准备好了,供水公司就可以开始送水了.嘟嘟一次只能处理一项送水任务,等到当前的送水任务完成了,才能处理下一项. 在处理每项送水任务之前,路径上的水管都要进行一系列的准备操作,如清洗.消毒等等.嘟嘟在

BZOJ_2594_[Wc2006]水管局长数据加强版_LCT

Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一条从A至B的水管的路径,接着通过信息化的控制中心通知路径上的水管进入准备送水状态,等到路径上每一条水管都准备好了,供水公司就可以开始送水了.嘟嘟一次只能处理一项送水任务,等到当前的送水任务完成了,才能处理下一项. 在处理每项送水任务之前,路径上的水管都要进行一系列的准备操作,如清洗.消毒等等.嘟嘟在

BZOJ 2594 Wc2006 水管局长数据加强版 Link-Cut-Tree

题目大意:给定一个无向图,多次删除某条边,多次查询两点之间路径上边权最大值的最小值 Link-Cut-Tree维护动态最小生成树 首先倒着做 将所有被删除的边标记(找边我用的排序+二分) 将没标记的边跑一遍Kruskal 求出最小生成树 然后每次加边和查询正常维护即可 LInk-Cut-Tree一气呵成写完,Kruskal尼玛写挂了-- 居然忘记把并查集连边 这我也是醉了 顺便吐槽一下题干上给的读入优化真尼玛弱--自己随便写一个都可以优化到RANK前十-- #include<cstdio> #

BZOJ 2594 [Wc2006]水管局长数据加强版 LCT

题意:链接 方法: LCT 解析: 搞了一个上午加1个小时的题,TM最后大错误居然是排序元素太多排不回原来的样子! 我要重新学排序! 这题是用LCT维护动态最小生成树,但是最小生成树上删边应该是做不到的,所以我们可以离线操作,之后先把所有该删的边删了然后倒着搞所有询问,这样删边就变成了加边,之后询问就是x到y路径上的最大边权. 图是动态的,所以想到LCT,但是LCT不能搞最大边权怎么办! 把每个边看做一个点. 假设这是第i个边,那么把他看做第i+n个点. 显然点权就是边权,然后将这个边连接的两个