树链剖分莫名MLE(10^5-10^6大小数组
查看原帖
树链剖分莫名MLE(10^5-10^6大小数组
214561
周凸加油楼主2020/7/31 15:18
#include<bits/stdc++.h>
#define ll long long
#define r(x) x = read()
#define rep(i,l,r) for(ll i = l; i <= r; i++)
#define mid ((l+r)>>1)
using namespace std;
const ll N = 4e4,Q = 2e5;
ll n,q,ans;
char opt[5],a,b;
ll arr[N];
struct Edge{
	ll nxt,to;
} e[N<<1];
ll cnt,head[N];
inline void add(ll u,ll v)
{
	e[++cnt].to = v;
	e[cnt].nxt = head[u];
	head[u] = cnt;
}
inline ll read()
{
	ll x = 0,f = 1;
	char ch = getchar();
	while( !isdigit(ch) ) { if( ch == '-' ) f = -1; ch = getchar(); }
	while( isdigit(ch) ) { x = (x<<1) + (x<<3) + (ch^48); ch = getchar(); }
	return x*f;
}
ll dep[N],f[N],size[N],son[N];
void dfs1(ll u,ll fa)
{
	dep[u] = dep[fa] + 1;
	f[u] = fa;
	size[u] = 1;
	for(ll i = head[u]; i; i = e[i].nxt)
	{
		ll v = e[i].to;
		if( v == fa ) continue;
		dfs1(v,u);
		size[u] += size[v];
		if( size[v] > size[ son[u] ] ) son[u] = v;
	}
}
ll top[N],dfn[N],rk[N];
ll dfnum;
void dfs2(ll u,ll tp)
{
	top[u] = tp;
	dfn[u] = ++dfnum, rk[dfnum] = u;
	if( son[u] ) dfs2(son[u],tp);
	for(ll i = head[u]; i; i = e[i].nxt)
	{
		ll v = e[i].to;
		if( dfn[v] ) continue;
		dfs2(v,v); 
	}
}
ll sum[N<<2],mx[N<<2];
void build(ll o,ll l,ll r)
{
	if( l == r )
	{
		sum[o] = arr[ rk[l] ];
		mx[o] = arr[ rk[l] ];
		return;
	}
	build(o<<1,l,mid);
	build(o<<1|1,mid+1,r);
	sum[o] = sum[o<<1] + sum[o<<1|1];
	mx[o] = max(mx[o<<1], mx[o<<1|1]);
}
void update(ll o,ll l,ll r,ll u,ll del)
{
	if( l == r ) 
	{
		sum[o] = del, mx[o] = del;
		return;
	}
	if( u <= mid ) update(o<<1,l,mid,u,del);
	if( u >= mid+1 ) update(o<<1|1,mid+1,r,u,del);
	sum[o] = sum[o<<1] + sum[o<<1|1];	
	mx[o] = max(mx[o<<1], mx[o<<1|1]);
}
ll qm(ll o,ll l,ll r,ll L,ll R)
{
	if(L<=l&&r<=R) return mx[o];
	ll tot = 0;
	if( L <= mid ) tot = max( tot , qm(o<<1,l,mid,L,R) );
	if( R >= mid+1 ) tot = max( tot , qm(o<<1|1,mid+1,r,L,R) );
	return tot;
}
ll qs(ll o,ll l,ll r,ll L,ll R)
{
	if(L<=l&&r<=R) return sum[o];
	ll tot = 0;
	if( L <= mid ) tot += qs(o<<1,l,mid,L,R);
	if( R >= mid+1 ) tot += qs(o<<1|1,mid+1,r,L,R);
	return tot;
}
ll qmax_path(ll x,ll y)
{
	ll tot = 0;
	if( dep[ top[x] ] < dep[ top[y] ] ) swap(x,y);
	while( top[x] != top[y] )
	{
		if( dep[ top[x] ] < dep[ top[y] ] ) swap(x,y);
		tot = max(tot, qm(1,1,n,dfn[ top[x] ],dfn[x]) );
		x = f[ top[x] ];
	}
	if( dep[ x ] < dep[ y ] ) swap(x,y);
	tot = max(tot, qm(1,1,n,dfn[y],dfn[x]) );
	return tot;
}
ll qsum_path(ll x,ll y)
{
	ll tot = 0;
	if( dep[ top[x] ] < dep[ top[y] ] ) swap(x,y);
	while( top[x] != top[y] )
	{
		if( dep[ top[x] ] < dep[ top[y] ] ) swap(x,y);
		tot += qs(1,1,n,dfn[ top[x] ],dfn[x]);
		x = f[ top[x] ];
	}
	if( dep[x] < dep[y] ) swap(x,y);
	tot += qs(1,1,n,dfn[y],dfn[x]); 
	return tot;
}
void init(){ dfs1(1,0); dfs2(1,1); build(1,1,n); }
int main()
{
	r(n);
	rep(i,1,n-1)
	{
		ll a,b;
		r(a), r(b);
		add(a,b);
		add(b,a);
	}
	rep(i,1,n) r( arr[i] );
	init();
	r(q);
	ll fucker = qs(1,1,n,1,3);
	rep(i,1,q)
	{
		scanf("%s",opt);
		r(a), r(b);
		if( opt[1] == 'H' ) update(1,1,n,a,b);
		if( opt[1] == 'M' ) ans = qmax_path(a,b);
		if( opt[1] == 'S' ) ans = qsum_path(a,b);
		if( opt[1] != 'H' ) printf("%lld\n",ans);
	}
}
2020/7/31 15:18
加载中...