换根+树剖,90分, wrong answer on test 10
查看原帖
换根+树剖,90分, wrong answer on test 10
233198
starseven楼主2020/9/2 17:01
/*
start in 14:52:49, september 2nd 

wrong answer in 16:13:32 ,september 2nd 

wrong answer in 16:18:20 , september 2nd
*/
#include<cstdio>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define Starseven main
#define ll long long
namespace lyt {
	void read(int &x){
	char ch=getchar();int re=0,op=1;
	while(ch<'0'||ch>'9'){if(ch=='-') op=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){re=(re<<3)+(re<<1)+ch-'0';ch=getchar();}
	x = re * op;
	return ;
	}
	void read(long long &x){
	char ch=getchar();long long re=0,op=1;
	while(ch<'0'||ch>'9'){if(ch=='-') op=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){re=(re<<3ll)+(re<<1ll)+ch-'0';ch=getchar();}
	x = re * op;
	return ;
	}
	void write(int x){
		if(x<0){putchar('-');x=-x;}
		if(x>9) write(x/10);
		putchar(x%10+'0');
		return ;
	}//记得自己加空格和换行 
	void write(long long x){
		if(x<0){putchar('-');x=-x;}
		if(x>9) write(x/10);
		putchar(x%10+'0');
		return ;
	}//记得自己加空格和换行
	int max(int x,int y){return x<y?y:x;}
	int min(int x,int y){return x<y?x:y;}
	int abs(int x){return x<0?-x:x;}
	long long max(long long x,long long y){return x<y?y:x;}
	long long min(long long x,long long y){return x<y?x:y;}
	long long abs(long long x){return x<0?-x:x;}
	double max(double x,double y){return x<y?y:x;}
	double min(double x,double y){return x<y?x:y;}
	double abs(double x){return x<0?-x:x;}
	void swap(int &a,int &b) {a ^= b ^= a ^= b;}
	void swap(long long &a,long long &b) {a ^= b ^= a ^= b;}
	ll Power(ll a, ll b, ll p) {
		ll re = 1;
		while(b) {
			if(b & 1ll) re = (re * a) % p;
			b >>= 1ll;
			a = (a * a) % p; 
		}
		return re;
	}
	int Power(int a, int b, int p) {
		int re = 1;
		while(b) {
			if(b & 1) re = 1ll * re * a % p;
			b >>= 1;
			a = 1ll * a * a % p; 
		}
		return re;
	}
}using namespace lyt;
const int N = 4e6 + 20;
int n, tail[N], cot, cnt, root, Lca[N][20];
ll va[N]; 
struct mp {
	int next, to;
}fp[N << 1];
struct Cut {
	int id, dep, size, wson, fa, top;
}t[N];
struct seg {
	ll minn, tag;
}tr[N << 2];

void Maketo(int from, int to) {
	fp[++cot].next = tail[from];
	fp[cot].to = to;
	tail[from] = cot;
	return ;
}

struct segment_tree {
	#define ls (id << 1)
	#define rs (id << 1 | 1)
	#define mid (l + r >> 1)
	#define check (x <= l && y >= r)
	void Pushup(int id) {
		tr[id].minn = min(tr[ls].minn, tr[rs].minn);
		return ;
	}
	
	void Pushdown(int id) {
		if(!tr[id].tag) return ;
		tr[ls].minn = tr[id].tag;
		tr[rs].minn = tr[id].tag;
		tr[ls].tag = tr[id].tag;
		tr[rs].tag = tr[id].tag;
		tr[id].tag = 0;
		return ;
	}
	
	void Build_tree(int l, int r, int id) {
		if(l == r) {
			tr[id].minn = va[l];
			tr[id].tag = 0;
			return ;
		}
		Build_tree(l, mid, ls);
		Build_tree(mid + 1, r, rs);
		Pushup(id);
	}
	
	void Change(int l, int r, int x, int y, int id, ll k) {
		if(check) {
			tr[id].minn = k;
			tr[id].tag = k;
			return ;
		}
		Pushdown(id);
		if(x <= mid) Change(l, mid, x, y, ls, k);
		if(y > mid) Change(mid + 1, r, x, y, rs, k);
		Pushup(id);
	}
	
	ll Find(int l, int r, int x, int y, int id) {
		if(check) return tr[id].minn;
		Pushdown(id);
		ll minn = 99999999999999;
		if(x <= mid) minn = min(minn, Find(l, mid, x, y, ls));
		if(y > mid) minn = min(minn, Find(mid + 1, r, x, y, rs));
		return minn;
	}
	#undef ls
	#undef rs
	#undef mid
	#undef check
}tree;

struct Tree_cut {
	void Dfs1(int x, int fa) {
		t[x].fa = fa;
		t[x].dep = t[fa].dep + 1;
		t[x].size = 1;
		for (int i = tail[x]; i; i = fp[i].next) {
			int y = fp[i].to;
			if(y == fa) continue;
			Lca[y][0] = x;
			for (int j = 1; j <= 20; j++)
				Lca[y][j] = Lca[ Lca[y][j - 1] ][j - 1];
			Dfs1(y, x);
			if(!t[x].wson || t[ t[x].wson ].size < t[y].size)
				t[x].wson = y;
			t[x].size += t[y].size;	
		}
		return ;
	}
	
	void Dfs2(int x, int tp) {
		t[x].id = ++cnt;
		t[x].top = tp;
		if(!t[x].wson) return ;
		Dfs2(t[x].wson, tp);
		for (int i = tail[x]; i; i = fp[i].next) {
			int y = fp[i].to;
			if(y == t[x].fa) continue;
			if(y == t[x].wson) continue;
			Dfs2(y, y);
		}
	}
	
	int Get_Lca(int u, int v) {
		if(t[u].dep < t[v].dep)
			swap(u, v);
		for (int i = 20; i >= 0; i--)
			if(t[ Lca[u][i] ].dep > t[v].dep)
				u = Lca[u][i];
		return u;			
	}
	
	void Change(int u, int v, ll k) {
		while(t[u].top != t[v].top) {
			if(t[ t[u].top ].dep < t[ t[v].top ].dep)
				swap(u, v);
			tree.Change(1, n, t[ t[u].top ].id, t[u].id, 1, k);
			u = t[ t[u].top ].fa;	
		}
		if(t[u].dep > t[v].dep)
			swap(u, v);
		tree.Change(1, n, t[u].id, t[v].id, 1, k);
		return ;	
	}
	
}cut;

int Starseven(void) {
//	freopen("P3979_10.in","r",stdin);
//	freopen("P3979.in","w", stdout);
	int m;
	read(n);
	read(m);
	for (int i = 1; i < n; i++) {
		int u, v;
		read(u);
		read(v);
		Maketo(u, v);
		Maketo(v, u);
	}
	cut.Dfs1(1, 0);
	cut.Dfs2(1, 1);
	for (int i = 1; i <= n; i++) {
		read(va[ t[i].id ]);
	}
	tree.Build_tree(1, n, 1);
	read(root);
	while(m--) {
		int opt;
		read(opt);
		if(opt == 1)
			read(root);
		else if(opt == 2) {
			int p1, p2;
			ll v;
			read(p1);
			read(p2);
			read(v);
			cut.Change(p1, p2, v);
		}
		else {
			int x;
			read(x);
			if(x == root) {
				write(tr[1].minn);
				puts("");
				continue;
			}
			else if(root == 1) {
				write(tree.Find(1, n, t[x].id, t[x].id + t[x].size - 1, 1));
				puts("");
				continue;
			}
			else if(t[x].id < t[root].id && t[root].id <= t[x].id + t[x].size - 1) {
				x = cut.Get_Lca(root, x);
				ll ans = 9999999999999999;
				ans = min(ans, tree.Find(1, n, 1, t[x].id - 1, 1));
				ans = min(ans, tree.Find(1, n, t[x].id + t[x].size, n, 1));	
				write(ans);
				puts("");
				continue;
			}
			else {
				write(tree.Find(1, n, t[x].id, t[x].id + t[x].size - 1, 1));
				puts("");
				continue;
			}
		}
	}
	return 0;	
}
2020/9/2 17:01
加载中...