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);
}
}

【BZOJ2631】tree的更多相关文章

  1. 【bzoj2631】tree link-cut-tree

    2016-06-01 08:50:36 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2631 注意加和乘的标记下传问题. 还有就是split后 ...

  2. 【bzoj2631】tree LCT

    题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一:+ u v c:将u到v的路径上的点的权值都加上自然数c:- u1 v1 u2 v2:将树中原有的边( ...

  3. 【POJ3237】Tree 树链剖分+线段树

    [POJ3237]Tree Description You are given a tree with N nodes. The tree's nodes are numbered 1 through ...

  4. 【BZOJ】【2631】Tree

    LCT 又一道名字叫做Tree的题目…… 看到删边加边什么的……又是动态树问题……果断再次搬出LCT. 这题比起上道[3282]tree的难点在于需要像线段树维护区间那样,进行树上路径的权值修改&am ...

  5. 【Luogu1501】Tree(Link-Cut Tree)

    [Luogu1501]Tree(Link-Cut Tree) 题面 洛谷 题解 \(LCT\)版子题 看到了顺手敲一下而已 注意一下,别乘爆了 #include<iostream> #in ...

  6. 【BZOJ3282】Tree (Link-Cut Tree)

    [BZOJ3282]Tree (Link-Cut Tree) 题面 BZOJ权限题呀,良心luogu上有 题解 Link-Cut Tree班子提 最近因为NOIP考炸了 学科也炸了 时间显然没有 以后 ...

  7. 【AtCoder3611】Tree MST(点分治,最小生成树)

    [AtCoder3611]Tree MST(点分治,最小生成树) 题面 AtCoder 洛谷 给定一棵\(n\)个节点的树,现有有一张完全图,两点\(x,y\)之间的边长为\(w[x]+w[y]+di ...

  8. 【HDU5909】Tree Cutting(FWT)

    [HDU5909]Tree Cutting(FWT) 题面 vjudge 题目大意: 给你一棵\(n\)个节点的树,每个节点都有一个小于\(m\)的权值 定义一棵子树的权值为所有节点的异或和,问权值为 ...

  9. 【BZOJ2654】Tree(凸优化,最小生成树)

    [BZOJ2654]Tree(凸优化,最小生成树) 题面 BZOJ 洛谷 题解 这道题目是之前\(Apio\)的时候写的,忽然发现自己忘记发博客了... 这个万一就是一个凸优化, 给所有白边二分一个额 ...

随机推荐

  1. left join 注意事项

    相信对于熟悉SQL的人来说,LEFT JOIN非常简单,采用的时候也很多,但是有个问题还是需要注意一下.假如一个主表M有多个从表的话A B C …..的话,并且每个表都有筛选条件,那么把筛选条件放到哪 ...

  2. Java实现bt文件下载、制作、解析、磁力链接

    首先torrent里面肯定携带的有一些信息,所以就需要我们来解析这些信息. 我们这里做多文件制作torrent,所以首先要针对每一个文件建一个实体类 import java.util.List; pu ...

  3. Svg.Js A标签,链接操作

    一.创建a标签,为a标签添加内容 <div id="svg1"></div> <script> //SVG.A 链接创建 var draw = ...

  4. 《成神之路-基础篇》JVM——Java内存模型(已完结)

    Java内存模型 本文是<成神之路系列文章>的第一篇,主要是关于JVM的一些介绍. 持续更新中 Java内存模型 JVM内存结构 VS Java内存模型 VS Java对象模型(Holli ...

  5. 深入分析ReentrantLock公平锁和非公平锁的区别

    在ReentrantLock中包含了公平锁和非公平锁两种锁,通过查看源码可以看到这两种锁都是继承自Sync,而Sync又继承自AbstractQueuedSynchronizer,而AbstractQ ...

  6. Inferred type 'S' for type parameter 'S' is not within its bound; should extend

    在使用springboot 方法报错: Inferred type 'S' for type parameter 'S' is not within its bound; should extends ...

  7. 第一章 Java加解密简介

    1.加密算法: 移位.替代(古典加密) 对称加密:DES.AES 非对称加密:RSA 散列函数算法(单向加密):MD5.SHA.Mac 数字签名算法:RSA.DSA 其中,前三种主要完成数据的加解密: ...

  8. html table奇偶行颜色设置 (CSS选择器)

    :nth-child(n) 选择器匹配属于其父元素的第 N 个子元素,不论元素的类型.n 可以是数字.关键词或公式. 下面的例子, 设置表格的奇偶行背景颜色不同:单独设置表格的第1列背景颜色不同. & ...

  9. solr建立pdf/word/excel索引的方法

    PS: 本文假设你已经成功的搭建了一个Solr服务器步骤如下:(1)准备好一份Solr的源码,假设现在保存在c:\apache-solr-1.4.1\目录下(2)从https://issues.apa ...

  10. 判断checkbox选中的个数

    直接看例子吧: shippingAddressList  为一个集合 <c:forEach items="${shippingAddressList }" var=" ...