【BZOJ2631】tree

本文深入探讨了一种基于树形结构的操作算法,详细解释了四种操作:加权、删除边、乘权和求路径权值和。通过实例演示算法实现,并提供了输入输出样例。重点介绍了使用LCT(轻重链分解)来高效处理加权和乘权操作,以及如何避免删除边以保持树的连通性。

Description

 一棵n个点的树,每个点的初始权值为1。对于这棵树有q个操作,每个操作为以下四种操作之一:
+ u v c:将u到v的路径上的点的权值都加上自然数c;
- u1 v1 u2 v2:将树中原有的边(u1,v1)删除,加入一条新边(u2,v2),保证操作完之后仍然是一棵树;
* u v c:将u到v的路径上的点的权值都乘上自然数c;
/ u v:询问u到v的路径上的点的权值和,求出答案对于51061的余数。

Input

  第一行两个整数n,q
接下来n-1行每行两个正整数u,v,描述这棵树
接下来q行,每行描述一个操作
Output

  对于每个/对应的答案输出一行
Sample Input

3 2

1 2

2 3

  • 1 3 4

/ 1 1

Sample Output

4

HINT

数据规模和约定

10%的数据保证,1<=n,q<=2000

另外15%的数据保证,1<=n,q<=5*10^4,没有-操作,并且初始树为一条链

另外35%的数据保证,1<=n,q<=5*10^4,没有-操作

100%的数据保证,1<=n,q<=10^5,0<=c<=10^4

Source

显然直接LCT就行了…给加和乘打下标记就可以.
记得计算时候要split而不是cut…不要删边!!!
我傻逼把加和乘的标记写成了bool…WA了4发233

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN 100010
#define LL unsigned int
#define P 51061
using namespace std;
char ch[3];
int u,v,w;
int n,m;
int sta[MAXN],top;
struct splay
{
    int fa,ch[2],size;
    bool rev;
    LL sum,w,time,plus;
}tree[MAXN];
void in(int &x)
{
    char ch=getchar();int flag=1;x=0;
    while (!(ch>='0'&&ch<='9')) flag=ch=='-'?-1:1,ch=getchar();
    while (ch>='0'&&ch<='9')    x=x*10+ch-'0',ch=getchar();x*=flag;
}
bool is_root(int x)
{
    return tree[tree[x].fa].ch[0]!=x&&tree[tree[x].fa].ch[1]!=x;
}
void push_up(int x)
{
    tree[x].sum=(tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].sum+tree[x].w)%P;
    tree[x].size=(tree[tree[x].ch[0]].size+tree[tree[x].ch[1]].size+1)%P;
}
void calc(int x,int tim,int plu)
{
    if (!x) return;
    tree[x].w=(tree[x].w*tim+plu)%P;
    tree[x].sum=(tree[x].sum*tim+plu*tree[x].size)%P;
    tree[x].plus=(tree[x].plus*tim+plu)%P;
    tree[x].time=(tree[x].time*tim)%P;
}
void push_down(int x)
{
    if (tree[x].rev)
    {
        tree[x].rev^=1;tree[tree[x].ch[0]].rev^=1;tree[tree[x].ch[1]].rev^=1;
        swap(tree[x].ch[0],tree[x].ch[1]);
    }
    if (tree[x].time!=1||tree[x].plus!=0)   calc(tree[x].ch[0],tree[x].time,tree[x].plus),calc(tree[x].ch[1],tree[x].time,tree[x].plus);
    tree[x].time=1;tree[x].plus=0;
}
void rot(int x)
{
    int y=tree[x].fa,z=tree[y].fa,l,r;
    l=(tree[y].ch[1]==x);r=l^1;
    if (!is_root(y))    tree[z].ch[tree[z].ch[1]==y]=x;
    tree[tree[x].ch[r]].fa=y;tree[y].fa=x;tree[x].fa=z;
    tree[y].ch[l]=tree[x].ch[r];tree[x].ch[r]=y;
    push_up(y);push_up(x);
}
void Splay(int x)
{
    sta[++top]=x;
    for (int i=x;!is_root(i);i=tree[i].fa)  sta[++top]=tree[i].fa;
    while (top) push_down(sta[top--]);
    while (!is_root(x))
    {
        int y=tree[x].fa,z=tree[y].fa;
        if (!is_root(y))
        {
            if (tree[y].ch[0]==x^tree[z].ch[0]==y)  rot(x);
            else    rot(y);
        }
        rot(x);
    }
}
void access(int x)
{
    for (int i=0;x;i=x,x=tree[x].fa)    Splay(x),tree[x].ch[1]=i,push_up(x);
}
void make_root(int x)
{
    access(x);Splay(x);tree[x].rev^=1;
}
void link(int x,int y)
{
    make_root(x);tree[x].fa=y;
}
void split(int x,int y)//为了获得信息要拆子树但是不能删边!!! 
{
    make_root(y);access(x);Splay(x);
}
void cut(int x,int y)
{
    make_root(x);access(y);Splay(y);tree[y].ch[0]=tree[x].fa=0;
}
int main()
{
    in(n);in(m);
    for (int i=1;i<=n;i++)  tree[i].w=tree[i].sum=tree[i].size=tree[i].time=1;
    for (int i=1;i<n;i++)
    {
        in(u);in(v);
        link(u,v);
    }
    while (m--)
    {
        scanf("%s",ch);in(u);in(v);
        if (ch[0]=='+') in(w),split(u,v),calc(u,1,w);
        if (ch[0]=='-') cut(u,v),in(u),in(v),link(u,v);
        if (ch[0]=='*') in(w),split(u,v),calc(u,w,0);
        if (ch[0]=='/') split(u,v),printf("%u\n",tree[u].sum);
    }
}
Mtree is a powerful tree creation tool for the Unity editor. Nominated for best Artistic Tool 2019 Unity Awards. Every game needs vegetation, and while there are numerous vegetation packs for sale on the asset store, nothing beats the usefulness of having total control over the look and performance of the assets. Mtree will not only create beautiful looking vegetation, it will streamline your workflow by removing the need of modelling, unwrapping, importing your vegetation models from another software, and doing it all over again when you need to change a small detail. With Mtree, there will be less iterations over your models, and they will be quicker. Mtree trees are made in unity, for unity, the material is right, the dimensions are right, and everything is simple. Moreover, a good mesh is not enough in order to have a believable vegetation asset, you need a good shader, a good wind displacement solution, and vertex data to feed those; Mtree will answer every one of these needs. Mtree offers an intuitive, simple, yet complete solution for crafting AAA trees in a matter of minutes. With Mtree you can: • Create a trunk of any shape. • Add branches, grow them, split stem, add more branches. • Add leafs of any shape. • Bake the ambient occlusion in the vertex data. • Control the polygon count, get the most out of the fewest triangles. • Create Branches textures from a single leaf texture with the Branch Editor. • Save your finished tree as a prefab that is convenient to use. What Mtree will do for you: • Automatically create LOD levels. • Create and assign materials to the bark and leaves of your trees. • Make branches react to the colliders of your scene. • Create and render a billboard when you save the tree as prefab. • Bake the ambient occlusion when you save the tree as prefab. • Create vertex color data that will be used to drive the wind simulation and random color variation.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值