2 条题解

  • 0
    @ 2026-2-10 15:01:26
    #include<bits/stdc++.h>
    using namespace std;
    const int N=2e5+10;
    #define int long long
    #define lc(p) tr[p].ch[0]
    #define rc(p) tr[p].ch[1]
    #define fa(p) tr[p].f
    struct node{int ch[2],f,s,v,sum,tag;}tr[N];
    bool notrt(int p){return lc(fa(p))==p||rc(fa(p))==p;}
    void pushup(int p){tr[p].s=tr[lc(p)].s+tr[rc(p)].s+tr[p].v+tr[p].sum;}
    void pushdown(int p)
    {
    	if(tr[p].tag)
    	{
    		swap(lc(p),rc(p));
    		tr[lc(p)].tag^=1;tr[rc(p)].tag^=1;
    		tr[p].tag=0;
    	}
    } 
    void pushall(int p)
    {
    	if(notrt(p))pushall(fa(p));
    	pushdown(p);
    }
    void rotate(int x)
    {
    	int y=fa(x),z=fa(y),k=rc(y)==x;
    	if(notrt(y))tr[z].ch[rc(z)==y]=x;fa(x)=z;
    	tr[y].ch[k]=tr[x].ch[k^1],fa(tr[x].ch[k^1])=y;
    	tr[x].ch[k^1]=y;fa(y)=x;
    	pushup(y);pushup(x);
    }
    void splay(int x)
    {
    	pushall(x);
    	while(notrt(x))
    	{
    		int y=fa(x),z=fa(y);
    		if(notrt(y))((rc(y)==x)^(rc(z)==y))?rotate(x):rotate(y);
    		rotate(x);
    	}
    }
    void access(int x)
    {
    	for(int y=0;x;)
    	{
    		splay(x);
    		tr[x].sum+=tr[rc(x)].s-tr[y].s;
    		rc(x)=y;
    		pushup(x);
    		y=x;x=fa(x);
    	}
    }
    void makert(int x)
    {
    	access(x);
    	splay(x);
    	tr[x].tag^=1;
    }
    void split(int x,int y)
    {
    	makert(x);
    	access(y);
    	splay(y);
    }
    void link(int x,int y)
    {
    	makert(x);makert(y);
    	fa(x)=y;tr[y].sum+=tr[x].s;pushup(y);
    }
    void cut(int x,int y)
    {
    	split(x,y);
    	fa(x)=lc(y)=0;
    }
    signed main()
    {
    	int n,q;cin>>n>>q;
    	for(int i=1;i<=n;i++)cin>>tr[i].v;
    	for(int i=1;i<n;i++)
    	{
    		int x,y;cin>>x>>y;x++,y++;
    		link(x,y);
    	}
    	while(q--)
    	{
    		int op;cin>>op;
    		if(op==0)
    		{
    			int x1,y1,x2,y2;cin>>x1>>y1>>x2>>y2;
    			x1++,x2++,y1++,y2++;
    			cut(x1,y1);link(x2,y2);
    		}
    		if(op==1)
    		{
    			int x,k;cin>>x>>k;x++;
    			makert(x);
    			tr[x].v+=k;
    			pushup(x);
    		}
    		if(op==2)
    		{
    			int x,y;cin>>x>>y;x++,y++;
    			split(x,y);
    			cout<<tr[x].s<<'\n';
    		}
    	}
    	return 0;
    }
    • -1
      @ 2026-8-13 15:06:48

      100100 行的代码......

      #include<bits/stdc++.h>
      using namespace std;
      #define ll long long
      const ll N=2e5+10;
      #define lc(p) tr[p].ch[0]
      #define rc(p) tr[p].ch[1]
      #define fa(p) tr[p].f
      struct node{ll ch[2],f,s,v,sum,tag;}tr[N];
      bool nl(ll p){return lc(fa(p))==p||rc(fa(p))==p;}
      void pushup(ll p){tr[p].s=tr[lc(p)].s+tr[rc(p)].s+tr[p].v+tr[p].sum;}
      void pushdown(ll p)
      {
      	if(tr[p].tag)
      	{
      		swap(lc(p),rc(p));
      		tr[lc(p)].tag^=1;tr[rc(p)].tag^=1;
      		tr[p].tag=0;
      	}
      }
      void pushall(ll p)
      {
      	if(nl(p))pushall(fa(p));
      	pushdown(p);
      }
      void rotate(ll x)
      {
      	ll y=fa(x),z=fa(y),k=(rc(y)==x);
      	if(nl(y))tr[z].ch[rc(z)==y]=x;fa(x)=z;
      	tr[y].ch[k]=tr[x].ch[k^1],fa(tr[x].ch[k^1])=y;
      	tr[x].ch[k^1]=y;fa(y)=x;
      	pushup(y);pushup(x);
      }
      void splay(ll x)
      {
      	pushall(x);
      	while(nl(x))
      	{
      		ll y=fa(x),z=fa(y);
      		if(nl(y))((rc(y)==x)^(rc(z)==y))?rotate(x):rotate(y);
      		rotate(x);
      	}
      }
      void access(ll x)
      {
      	for(ll y=0;x;y=x,x=fa(x))
      	{
      		splay(x);
      		tr[x].sum+=tr[rc(x)].s-tr[y].s;
      		rc(x)=y;
      		pushup(x);
      	}
      }
      void makert(ll x)
      {
      	access(x);splay(x);
      	tr[x].tag^=1;
      }
      void split(ll x,ll y){makert(x);access(y);splay(y);}
      void link(ll x,ll y)
      {
      	makert(x);makert(y);
      	fa(x)=y;tr[y].sum+=tr[x].s;
      	pushup(y);
      }
      void cut(ll x,ll y)
      {
      	split(x,y);
      	fa(x)=lc(y)=0;
      }
      int main()
      {
      	ll n,q;scanf("%lld%lld",&n,&q);
      	for(ll i=1;i<=n;i++)scanf("%lld",&tr[i].v);
      	for(ll i=1,x,y;i<n;i++)
      	{
      		scanf("%lld%lld",&x,&y);
      		link(x+1,y+1);
      	}
      	while(q--)
      	{
      		ll op,x,y,a,b;scanf("%lld%lld%lld",&op,&x,&y);x++;y++;
      		if(!op)
      		{
      			scanf("%lld%lld",&a,&b);a++;b++;
      			cut(x,y);link(a,b);
      		}
      		else if(op==1)
      		{
      			makert(x);
      			tr[x].v+=y-1;
      			pushup(x);
      		}
      		else
      		{
      			split(x,y);
      			printf("%lld\n",tr[x].s);
      		}
      	}
      	return 0;
      }
      
      • 1

      动态树顶点加子树求和(Dynamic Tree Vertex Add Subtree Sum)

      信息

      ID
      2341
      时间
      1000ms
      内存
      1024MiB
      难度
      7
      标签
      递交数
      26
      已通过
      8
      上传者