MnZn 刚学树剖,样例和hack都过但是WA0pts求调
查看原帖
MnZn 刚学树剖,样例和hack都过但是WA0pts求调
581316
small_john楼主2024/1/25 16:00
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5+5;
int n,U[N],V[N],m,cnt,son[N],sz[N],top[N],dfn[N],pre[N],idx,dep[N],f[N],tof[N];
int head[N],to[N<<1],g[N<<1],nxt[N<<1];
inline void add(int x,int y,int z)
{
	nxt[++cnt] = head[x];
	head[x] = cnt;
	to[cnt] = y,g[cnt] = z;
}
void dfs1(int u,int fa)
{
	f[u] = fa,sz[u] = 1,dep[u] = dep[fa]+1;
	for(int i = head[u];i;i = nxt[i])
	{
		int v = to[i];
		if(v==fa) continue;
		tof[v] = g[i];
		dfs1(v,u);
		sz[u]+=sz[v];
		if(sz[v]>sz[son[u]]) son[u] = v;
	}
}
void dfs2(int u,int tp)
{
	top[u] = tp,dfn[u] = ++idx,pre[idx] = u;
	if(!son[u]) return;
	dfs2(son[u],tp);
	for(int i = head[u];i;i = nxt[i])
	{
		int v = to[i];
		if(v==f[u]||v==son[u]) continue;
		dfs2(v,v);
	}
}
struct node{
    int mx,mn,sum,tag;
    inline friend node operator + (node x,node y)
    {
        node res;
        res.mx = max(x.mx,y.mx);
        res.mn = min(x.mn,y.mn);
        res.sum = x.sum+y.sum;
        res.tag = 0;
        return res;
    }
}t[N<<2];
#define ls (k<<1)
#define rs (k<<1|1)
inline void pushup(int k){t[k] = t[ls]+t[rs];}
inline void fan(int k){t[k].sum*=-1,t[k].mn*=-1,t[k].mx*=-1,swap(t[k].mn,t[k].mx),t[k].tag = 1-t[k].tag;}
inline void down(int k)
{
    if(t[k].tag)
    {
        fan(ls),fan(rs);
        t[k].tag = 0;
    }
}
void build(int k,int l,int r)
{
    t[k].tag = 0;
    if(l==r) return t[k].mx = t[k].mx = t[k].sum = tof[pre[l]],void();
    int mid = (l+r)/2;
    build(ls,l,mid),build(rs,mid+1,r);
    pushup(k);
}
void change1(int k,int l,int r,int x,int v)
{
    if(l==r) return t[k].mx = t[k].mx = t[k].sum = v,void();
    int mid = (l+r)/2;
    down(k);
    if(mid>=x) change1(ls,l,mid,x,v);
    else change1(rs,mid+1,r,x,v);
    pushup(k);
}
void change2(int k,int l,int r,int x,int y)
{
    if(l>y||r<x) return;
    if(l>=x&&r<=y) return fan(k);
    int mid = (l+r)/2;
    down(k);
    change2(ls,l,mid,x,y),change2(rs,mid+1,r,x,y);
    pushup(k);
}
node ask(int k,int l,int r,int x,int y)
{
    if(l>y||r<x) return (node){(int)-2e9,(int)2e9,0,0};
    if(l>=x&&r<=y) return t[k];
    int mid = (l+r)/2;
    down(k);
    return ask(ls,l,mid,x,y)+ask(rs,mid+1,r,x,y);
}
#undef ls
#undef rs
inline void changetree(int x,int y)
{
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		change2(1,1,n,dfn[top[x]],dfn[x]);
		x = f[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	change2(1,1,n,dfn[x]+1,dfn[y]);
}
inline node asktree(int x,int y)
{
    node res = (node){(int)-2e9,(int)2e9,0,0};
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        res = res+ask(1,1,n,dfn[top[x]],dfn[x]);
        // cout<<"ask"<<dfn[top[x]]<<' '<<dfn[x]<<' '<<tof[x]<<' '<<ask(1,1,n,dfn[top[x]],dfn[x]).sum<<'\n';
        x = f[top[x]];
    }
    // cout<<"sb"<<res.sum<<'\n';
    if(dep[x]>dep[y]) swap(x,y);
    // cout<<x<<' '<<y<<'\n';
    res = res+ask(1,1,n,dfn[x]+1,dfn[y]);
    return res;
}
signed main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n;
	for(int i = 1,u,v,w;i<n;i++)
		cin>>u>>v>>w,u++,v++,add(u,v,w),add(v,u,w),U[i] = u,V[i] = v;
	dfs1(1,0),dfs2(1,1);
    // for(int i = 1;i<=n;i++)
    //     cout<<top[i]<<' '<<dfn[i]<<' '<<tof[i]<<'\n';
	for(int i = 1;i<=n;i++)
		if(dep[U[i]]>dep[V[i]]) swap(U[i],V[i]);
    build(1,1,n);
    cin>>m;
    while(m--)
    {
        string op;int u,v;
        cin>>op>>u>>v;
        if(op[0]=='C') change1(1,1,n,dfn[V[u]],v);
        else if(op[0]=='N') changetree(u+1,v+1);
        else if(op[0]=='S') cout<<asktree(u+1,v+1).sum<<'\n';
        else if(op[1]=='A') cout<<asktree(u+1,v+1).mx<<'\n';
        else cout<<asktree(u+1,v+1).mn<<'\n';
    }
	return 0;
}
/*10
0 1 2
4 5 3
2 4 1
0 5 4
1 3 5
1 7 4
4 6 3
1 8 4
3 9 5
5
C 6 2
N 9 2
SUM 7 3
N 9 2
SUM 7 2*/
2024/1/25 16:00
加载中...