唐氏萌新史山代码求调教
查看原帖
唐氏萌新史山代码求调教
601236
_WHITE_NIGHT_楼主2024/5/29 19:41

RT link

#include<bits/stdc++.h>
using namespace std;
#define pii pair <int,int>
#define v first
#define w second
#define mp(x,y) make_pair(x,y)

namespace FastIO
{
	#define getch getchar
	inline int input()
	{
		int num = 0,f = 1;
		char ch = getch();
		while(ch < '0' || ch > '9')
		{
			if(ch == '-') f = -1;
			ch = getch();
		}
		while(ch >= '0' && ch <= '9')
		{
			num = (num << 1) + (num << 3) + (ch ^ 48);
			ch = getch();
		}
		return num * f;
	}
	
	inline void printNum(int num)
	{
		if(num >= 10) printNum(num / 10);
		putchar(num % 10 + 48);
	}
	
	inline void print(int num,char ch = ' ')
	{
		if(num < 0) putchar('-'),num = -num;
		printNum(num);
		putchar(ch);
	}
	#undef getch
}
using FastIO::input;
using FastIO::print;

const int N = 1e5 + 5;
const int INF = -1u / 2;
struct Edge {int u,v,w;};
struct SegmentTree
{
	struct Node
	{
		int l,r,val,add,cov;
		#define l(x) tree[x].l
		#define r(x) tree[x].r
		#define val(x) tree[x].val
		#define add(x) tree[x].add
		#define cov(x) tree[x].cov
		#define ave(x) (tree[x].l + tree[x].r >> 1)
	};
	#define mid (l + r >> 1)
	Node tree[N << 2];
	
	void build(int l,int r,int pos,int (&arr)[N])
	{
		l(pos) = l,r(pos) = r,cov(pos) = -INF;
		if(l == r)
		{
			val(pos) = arr[l];
			return;
		}
		build(l,mid,pos << 1,arr);
		build(mid + 1,r,pos << 1 | 1,arr);
		val(pos) = max(val(pos << 1),val(pos << 1 | 1));
	}
	
	void update(int pos,int Add,int Cov)
	{
		if(Cov != -INF) val(pos) = cov(pos) = Cov,add(pos) = 0;
		val(pos) += Add,add(pos) += Add;
	}
	
	void spread(int pos)
	{
		update(pos << 1,add(pos),cov(pos));
		update(pos << 1 | 1,add(pos),cov(pos));
		cov(pos) = -INF,add(pos) = 0;
	}
	
	void increase(int l,int r,int k,int pos)
	{
		if(l <= l(pos) && r(pos) <= r)
		{
			add(pos) += k,val(pos) += k;
			return;
		}
		spread(pos);
		if(l <= ave(pos)) increase(l,r,k,pos << 1);
		if(r > ave(pos)) increase(l,r,k,pos << 1 | 1);
		val(pos) = max(val(pos << 1),val(pos << 1 | 1));
	}
	
	void cover(int l,int r,int k,int pos)
	{
		if(l <= l(pos) && r(pos) <= r)
		{
			val(pos) = cov(pos) = k;
			return;
		}
		spread(pos);
		if(l <= ave(pos)) cover(l,r,k,pos << 1);
		if(r > ave(pos)) cover(l,r,k,pos << 1 | 1);
		val(pos) = max(val(pos << 1),val(pos << 1 | 1));
	}
	
	int query(int l,int r,int pos)
	{
		if(l <= l(pos) && r(pos) <= r)
			return val(pos);
		spread(pos);
		int res = -INF;
		if(l <= ave(pos)) res = max(res,query(l,r,pos << 1));
		if(r > ave(pos)) res = max(res,query(l,r,pos << 1 | 1));
		return res;
	}
	
	#undef l
	#undef r
	#undef val	
	#undef add
	#undef cov	
	#undef ave
	#undef mid	
};
int n,ts;
string s;
SegmentTree ST;
int fa[N],son[N],ext[N],dep[N],top[N],dfn[N],w[N];
vector <Edge> vec;
vector <pii> edge[N];

void getSon(int u,int from,int depth)
{
	fa[u] = from,dep[u] = depth,ext[u] = 1;
	
	for(auto tmp : edge[u])
	{
		int v = tmp.v;
		if(v == from) continue;
		getSon(v,u,depth + 1);
		ext[u] += ext[v];
		if(ext[v] > ext[son[u]]) son[u] = v;
	}
}

void getDfn(int u,int apex)
{
	dfn[u] = ++ts,top[u] = apex;
	
	if(!son[u]) return;
	getDfn(son[u],apex);
	
	for(auto tmp : edge[u])
	{
		int v = tmp.v;
		if(v != fa[u] && v != son[u])
			getDfn(v,v);
	}
}

void getWorth(int u,int worth)
{
	w[dfn[u]] = worth;
	for(auto tmp : edge[u])
	{
		int v = tmp.v;
		if(v != fa[u])
			getWorth(v,tmp.w);
	}
}

void change(int k,int w)
{
	int u = vec[k - 1].u,v = vec[k - 1].v;
	if(dfn[u] < dfn[v]) swap(u,v);
	ST.cover(dfn[u],dfn[u],w,1);
}

void cover(int u,int v,int k)
{
	while(top[u] != top[v])
	{
		if(dep[top[u]] < dep[top[v]])
			swap(u,v);
		ST.cover(dfn[top[u]],dfn[u],k,1);
		u = fa[top[u]];
	}
	if(dfn[u] < dfn[v]) swap(u,v);
	ST.cover(dfn[v] + 1,dfn[u],k,1);
}

void add(int u,int v,int k)
{
	while(top[u] != top[v])
	{
		if(dep[top[u]] < dep[top[v]])
			swap(u,v);
		ST.increase(dfn[top[u]],dfn[u],k,1);
		u = fa[top[u]];
	}
	if(dfn[u] < dfn[v]) swap(u,v);
	ST.increase(dfn[v] + 1,dfn[u],k,1);
}

int query(int u,int v)
{
	int ans = -INF;
	while(top[u] != top[v])
	{
		if(dep[top[u]] < dep[top[v]])
			swap(u,v);
		ans = max(ans,ST.query(dfn[top[u]],dfn[u],1));
		u = fa[top[u]];
	}
	if(dfn[u] < dfn[v]) swap(u,v);
	ans = max(ans,ST.query(dfn[v] + 1,dfn[u],1));
	return ans;
}

int main()
{
//	freopen("tree.in","r",stdin);
//	freopen("my.out","w",stdout);
	n = input();
	for(int i = 1;i < n;i++)
	{
		int u = input(),v = input(),w = input();
		edge[u].push_back(mp(v,w)),
		edge[v].push_back(mp(u,w));
		vec.push_back({u,v,w});
	}
	getSon(1,0,1);
	getDfn(1,1);
	getWorth(1,0);
	ST.build(1,n,1,w);
	
//	for(int i = 1;i <= n;i++)
//		print(ST.query(i,i,1));
//	puts("");
	
	while(cin >> s)
	{
		if(s == "Stop") break;
		int u = input(),v = input();
		if(s == "Change")
			change(u,v);
		if(s == "Cover")
			cover(u,v,input());
		if(s == "Add") 
			add(u,v,input());
		if(s == "Max") 
			print(query(u,v),'\n');
	}
}
2024/5/29 19:41
加载中...