[省选前题目整理][清橙A1303]tree(LCT)

题目链接

http://www.tsinsen.com/A1303

思路

非常好的LCT模板题。。。
乘法和加法lazy tag是可以叠加的,这个做法和线段树的lazy tag叠加是完全一样的。。。
刚开始pushdown标记很傻叉地写拙了,害得我盲调了半个多小时。。。郁闷。。。

代码

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>

#define MAXN 200000
#define MOD 51061
#define lson ch[o][0]
#define rson ch[o][1]

using namespace std;

typedef unsigned int uint;

int ch[MAXN][2],fa[MAXN],size[MAXN];
uint sum[MAXN],multag[MAXN],addtag[MAXN],val[MAXN];
int stack[MAXN],top=0;
bool rev[MAXN];

bool isRoot(int o)
{
    return ch[fa[o]][0]!=o&&ch[fa[o]][1]!=o;
}

void pushup(int o)
{
    sum[o]=(val[o]+sum[lson]+sum[rson])%MOD;
    size[o]=(size[lson]+size[rson]+1)%MOD;
}

void cal(int o,uint mulv,uint addv) //子树o对应区间先乘上mulv后加上addv
{
    if(!o) return;
    val[o]=((val[o]*mulv)%MOD+addv)%MOD;
    sum[o]=((sum[o]*mulv)%MOD+addv*size[o]%MOD)%MOD;
    addtag[o]=(addtag[o]*mulv+addv)%MOD; //!!!!!!
    multag[o]=(multag[o]*mulv)%MOD;
}

void pushdown(int o)
{
    if(rev[o])
    {
        rev[lson]^=1;
        rev[rson]^=1;
        swap(lson,rson);
        rev[o]=false;
    }
    if(multag[o]!=1||addtag[o]!=0) cal(lson,multag[o],addtag[o]),cal(rson,multag[o],addtag[o]); //!!!!!!!!!!
    multag[o]=1,addtag[o]=0;
}

void rot(int x)
{
    int y=fa[x],z=fa[y];
    int p,q;
    if(ch[y][0]==x) p=0;
    else p=1;
    q=p^1;
    if(!isRoot(y))
    {
        if(ch[z][0]==y) ch[z][0]=x;
        else ch[z][1]=x;
    }
    fa[x]=z,fa[y]=x;
    ch[y][p]=ch[x][q];
    fa[ch[x][q]]=y;
    ch[x][q]=y;
    pushup(y);
    pushup(x);
}

void splay(int x)
{
    top=0;
    stack[++top]=x;
    for(int i=x;!isRoot(i);i=fa[i]) stack[++top]=fa[i];
    for(int i=top;i>=1;i--) pushdown(stack[i]);
    while(!isRoot(x))
    {
        int y=fa[x],z=fa[y];
        if(!isRoot(y))
        {
            if((ch[y][0]==x)==(ch[z][0]==y)) rot(y);
            else rot(x);
        }
        rot(x);
    }
}

void access(int x) //打通x到根节点的关键路径
{
    int tmp=0;
    while(x)
    {
        splay(x);
        ch[x][1]=tmp;
        pushup(x); //!!!!!!
        tmp=x;
        x=fa[x];
    }
}

void makeroot(int x) //使x成为根节点
{
    access(x);
    splay(x);
    rev[x]^=1;
}

void link(int x,int y) //连接x,y,y是x的父亲
{
    makeroot(x);
    fa[x]=y;
}

void cut(int x,int y) //断开x,y,y是x父亲
{
    makeroot(x);
    access(y);
    splay(y);
    ch[y][0]=fa[x]=0;
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<n;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        link(u,v);
    }
    for(int i=1;i<=n;i++)
        val[i]=sum[i]=multag[i]=size[i]=1;
    for(int i=1;i<=m;i++)
    {
        char cmd[10];
        int x,y,addv,mulv;
        scanf("%s%d%d",cmd,&x,&y);
        if(cmd[0]=='+') //x到y路径加
        {
            scanf("%d",&addv);
            makeroot(x);
            access(y);
            splay(y);
            cal(y,1,addv);
        }
        else if(cmd[0]=='-') //cut and link
        {
            cut(x,y);
            scanf("%d%d",&x,&y);
            link(x,y);
        }
        else if(cmd[0]=='*') //路径乘法
        {
            scanf("%d",&mulv);
            makeroot(x);
            access(y);
            splay(y);
            cal(y,mulv,0);
        }
        else if(cmd[0]=='/') //路径和
        {
            makeroot(x);
            access(y);
            splay(y);
            printf("%d\n",sum[y]);
        }
    }
    return 0;
}
weixin073智慧旅游平台开发微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
python017基于Python贫困生资助管理系统带vue前后端分离毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值