[BZOJ2631]tree 动态树lct
2631: tree
Time Limit: 30 Sec Memory Limit: 128 MB
Submit: 5171 Solved: 1754
[Submit][Status][Discuss]
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-1行每行两个正整数u,v,描述这棵树
接下来q行,每行描述一个操作
Output
Sample Input
1 2
2 3
* 1 3 4
/ 1 1
Sample Output
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
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#define maxn 500005
#define ls(x) t[x].s[0]
#define rs(x) t[x].s[1]
#define ll long long
#define mod 51061
using namespace std;
inline ll read() {
ll x=,f=;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-;
for(;isdigit(ch);ch=getchar()) x=x*+ch-'';
return x*f;
}
struct data {
ll s[],fa,c,a,v,sum,size;
data(){c=;v=,a=,sum=,size=;}
bool rev;
}t[maxn];
bool isroot(int x) {return ls(t[x].fa)!=x&&rs(t[x].fa)!=x;}
void pushup(int x) {t[x].sum=t[ls(x)].sum+t[rs(x)].sum+t[x].v;t[x].sum%=mod;t[x].size=t[ls(x)].size+t[rs(x)].size+;}
void cal(int x,int ce,int add) {
t[x].sum=t[x].sum*ce+add*t[x].size;t[x].sum%=mod;
t[x].v=t[x].v*ce+add;t[x].v%=mod;
t[x].c*=ce;t[x].c%=mod;
t[x].a=t[x].a*ce+add;t[x].a%=mod;
}
void pushdown(int x) {
if(t[x].rev) {
swap(ls(x),rs(x));
t[ls(x)].rev^=;t[rs(x)].rev^=;t[x].rev^=;
}
int ce=t[x].c,add=t[x].a;
t[x].c=;t[x].a=;
cal(ls(x),ce,add);cal(rs(x),ce,add);
}
void rotate(int x) {
int y=t[x].fa,z=t[y].fa;
bool l=ls(y)!=x,r=l^;
if(!isroot(y)) t[z].s[t[z].s[]==y]=x;
t[x].fa=z;t[y].fa=x;t[y].s[l]=t[x].s[r];
t[t[x].s[r]].fa=y;t[x].s[r]=y;
pushup(y);pushup(x);
}
void pre(int x) {
if(!isroot(x)) pre(t[x].fa);
pushdown(x);
}
void splay(int x) {
pre(x);
while(!isroot(x)) {
int y=t[x].fa,z=t[y].fa;
if(!isroot(y)){
if(ls(y)==x^ls(z)==y) rotate(x);
else rotate(y);
}
rotate(x);
}
}
void access(int x) {for(int y=;x;y=x,x=t[x].fa) {splay(x);t[x].s[]=y;pushup(x);}}
void mroot(int x) {access(x);splay(x);t[x].rev^=;}
void link(int x,int y) {mroot(x);t[x].fa=y;}
void cut(int x,int y) {mroot(x);access(y);splay(y);t[y].s[]=t[x].fa=;pushup(y);}
int n,q;
int main() {
n=read(),q=read();
t[].a=t[].c=t[].sum=t[].size=;
for(int i=;i<n;i++) {int u=read(),v=read();link(u,v);}
for(int i=;i<=q;i++) {
char ch[];scanf("%s",ch);
if(ch[]=='+') {int u=read(),v=read();mroot(u);access(v);splay(v);ll tmp=read();cal(v,,tmp);}
if(ch[]=='-') {int u=read(),v=read();cut(u,v);u=read();v=read();link(u,v);}
if(ch[]=='*') {int u=read(),v=read();mroot(u);access(v);splay(v);ll tmp=read();cal(v,tmp,);}
if(ch[]=='/') {int u=read(),v=read();mroot(u);access(v);splay(v);printf("%lld\n",t[v].sum);}
}
return ;
}
/*
5 100
1 2 1 3 3 4 3 5
+ 4 5 3
/ 4 5
* 4 5 3
/ 4 5
- 3 4 4 5
/ 3 4
*/
[BZOJ2631]tree 动态树lct的更多相关文章
- hdu 5398 动态树LCT
GCD Tree Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Su ...
- hdu 5002 (动态树lct)
Tree Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
- HDU 4718 The LCIS on the Tree (动态树LCT)
The LCIS on the Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Oth ...
- LCT(link cut tree) 动态树
模板参考:https://blog.csdn.net/saramanda/article/details/55253627 综合各位大大博客后整理的模板: #include<iostream&g ...
- 动态树LCT小结
最开始看动态树不知道找了多少资料,总感觉不能完全理解.但其实理解了就是那么一回事...动态树在某种意思上来说跟树链剖分很相似,都是为了解决序列问题,树链剖分由于树的形态是不变的,所以可以通过预处理节点 ...
- [模板] 动态树/LCT
简介 LCT是一种数据结构, 可以维护树的动态加边, 删边, 维护链上信息(满足结合律), 单次操作时间复杂度 \(O(\log n)\).(不会证) 思想类似树链剖分, 因为splay可以换根, 用 ...
- 动态树LCT(Link-cut-tree)总结+模板题+各种题目
一.理解LCT的工作原理 先看一道例题: 让你维护一棵给定的树,需要支持下面两种操作: Change x val: 令x点的点权变为val Query x y: 计算x,y之间的唯一的最短路径的点 ...
- BZOJ 2631 tree 动态树(Link-Cut-Tree)
题目大意:维护一种树形数据结构.支持下面操作: 1.树上两点之间的点权值+k. 2.删除一条边.添加一条边,保证加边之后还是一棵树. 3.树上两点之间点权值*k. 4.询问树上两点时间点的权值和. 思 ...
随机推荐
- 关于如何利用原生js动态给一个空对象添加属性以及属性值
首先,回忆一下,访问对象属性一共有两种方法:点获取法和方括号获取法.而我们最常用的就是点获取法了.但是当我们遇到需要给对象动态添加属性和属性值时,点获取法好像就不太好用了,尤其是我们不知道属性名的时候 ...
- Java 对象及其内存控制
作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 更新:其实这里有好多的变戏法,只要你理解了他们在JVM的中的实现机制,就豁然开朗了.有时间我会把这些变戏法的东西 ...
- [C/C++] extern关键字详解以及与static、const区别
extern用法详解: 1. 声明外部实体 声明外部全局变量或对象,一般用于头文件中,表示在其它编译单元内定义的变量,链接时进行外部链接,如: extern int ivalue; 此时的extern ...
- 【bzoj1458】士兵占领 有上下界最小流
题目描述 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵.我们称这些士兵占领了整个棋盘当满足第i行至少放置了Li个士兵 ...
- json数据中的某一个字段进行快速排序quicksort
快速排序(Quicksort)是对冒泡排序的一种改进,是一种分而治之算法归并排序的风格. 核心的思想就是通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小 ...
- [BZOJ4212]神牛的养成计划
[BZOJ4212]神牛的养成计划 试题描述 Hzwer 成功培育出神牛细胞,可最终培育出的生物体却让他大失所望...... 后来,他从某同校女神 牛处知道,原来他培育的细胞发生了基因突变,原先决定神 ...
- 洛谷 P3477 [POI2008]PER-Permutation 解题报告
P3477 [POI2008]PER-Permutation 题目描述 Multiset is a mathematical object similar to a set, but each mem ...
- THUSC2014酱油记
Day0: 坐飞机到北京,然后报到...跟jason_yu分到一个房间,刚好可以蹭点RP.发现房间460RMB/晚,但再带一份早餐就500RMB,难道早餐是40RMB么...在一家川菜馆吃的午晚餐,感 ...
- 【CF edu 30 D. Merge Sort】
time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...
- bzoj 2426 【HAOI2010】工程选址 贪心
[HAOI2010]工厂选址 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 447 Solved: 308[Submit][Status][Disc ...