洛谷P1501 [国家集训队]Tree II(LCT)
题目描述
一棵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的余数。
输入输出格式
输入格式:
第一行两个整数n,q
接下来n-1行每行两个正整数u,v,描述这棵树
接下来q行,每行描述一个操作
输出格式:
对于每个/对应的答案输出一行
输入输出样例
说明
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
By (伍一鸣)
全程自己YY,调了一下午真累啊QWQ......
LCT的板子题,要维护子树和,加法标记,乘法标记和自身的值
放标记的时候先放乘法标记
至于为什么http://www.cnblogs.com/zwfymqz/p/8588693.html
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cstring>
#define int long long
const int mod = ;
using namespace std;
const int MAXN = 1e5+;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') {x = x * + c - ''; c = getchar();}
return x * f;
}
int N, Q;
#define ls(x) T[x].ch[0]
#define rs(x) T[x].ch[1]
#define fa(x) T[x].f
struct node {
int f, ch[], r, mul, add, siz, sum, val;
}T[MAXN];
bool IsRoot(int x) {
return T[fa(x)].ch[] != x && T[fa(x)].ch[] != x;
}
int ident(int x) {
return T[fa(x)].ch[] == x ? : ;
}
void connect(int x, int fa, int how) {
T[x].f = fa;
T[fa].ch[how] = x;
}
void update(int x) {
T[x].sum = (T[ls(x)].sum + T[rs(x)].sum + T[x].val ) % mod;
T[x].siz = T[ls(x)].siz + T[rs(x)].siz + ;
}
void rotate(int x) {
int Y = fa(x), R = fa(Y), Yson = ident(x), Rson = ident(Y);
int B = T[x].ch[Yson ^ ];
T[x].f = R;
if(!IsRoot(Y))
connect(x, R, Rson);
connect(B, Y, Yson);
connect(Y, x, Yson ^ );
update(Y);update(x);
}
void pushr(int x) {
if(T[x].r) {
swap(ls(x), rs(x));
T[ls(x)].r ^= ;
T[rs(x)].r ^= ;
T[x].r = ;
}
}
void pushmul(int x) {
T[ls(x)].val *= T[x].mul; T[ls(x)].val %= mod;
T[rs(x)].val *= T[x].mul; T[rs(x)].val %= mod;
T[ls(x)].sum *= T[x].mul; T[ls(x)].sum %= mod;
T[rs(x)].sum *= T[x].mul; T[rs(x)].sum %= mod;
T[ls(x)].add *= T[x].mul; T[ls(x)].add %= mod;
T[rs(x)].add *= T[x].mul; T[rs(x)].add %= mod;
T[ls(x)].mul *= T[x].mul; T[ls(x)].mul %= mod;
T[rs(x)].mul *= T[x].mul; T[rs(x)].mul %= mod;
T[x].mul = ;
}
void pushadd(int x) {
T[ls(x)].val += T[x].add; T[ls(x)].val %= mod;
T[rs(x)].val += T[x].add; T[rs(x)].val %= mod;
T[ls(x)].sum += T[ls(x)].siz * T[x].add; T[ls(x)].sum %= mod;
T[rs(x)].sum += T[rs(x)].siz * T[x].add; T[rs(x)].sum %= mod;
T[ls(x)].add += T[x].add; T[ls(x)].add %= mod;
T[rs(x)].add += T[x].add; T[rs(x)].add %= mod;
T[x].add = ;
}
void pushdown(int x) {
pushr(x);
pushmul(x);
pushadd(x);
}
int st[MAXN];
int fuck;
void splay(int x) {
int y = x, top = ;
st[++top] = y;
while(!IsRoot(y)) st[++top] = (y = fa(y));
while(top) pushdown(st[top--]);
for(int y = fa(x); !IsRoot(x); rotate(x), y = fa(x))
if(!IsRoot(y))
rotate( ident(x) == ident(y) ? y : x );
}
void access(int x) {
for(int y = ; x; x = fa(y = x))//tag
splay(x), rs(x) = y, update(x);
}
void makeroot(int x) {
access(x);
splay(x);
T[x].r ^= ;
}
void split(int x,int y) {
makeroot(x);
access(y);
splay(y);
}
void link(int x, int y) {
makeroot(x);
T[x].f = y;
}
int findroot(int x) {
access(x);
splay(x);
while(ls(x)) x = ls(x);
return x;
}
void cut(int x, int y) {
split(x, y);
//makeroot(x);
if(findroot(y) == x && fa(x) == y && !rs(x))
T[x].f = T[y].ch[] = , update(y);
}
main() {
freopen("a.in","r",stdin);
scanf("%lld%lld", &N, &Q);
for(int i = ; i <= N; i++)
T[i].val = , T[i].sum = , T[i].mul = , T[i].siz = , T[i].add = ;
for(int i = ; i <= N - ; i++) {
int x = read(), y = read();
link(x, y);
}
int fuck = ;
while(Q--) {
char c = ; int u1, v1, u2, v2, val;
while(c < '*') c = getchar();
scanf("%lld%lld", &u1, &v1);
if(c == '+') {
scanf("%lld", &val);
split(u1, v1);
T[v1].val += val; T[v1].val %= mod;
T[v1].add += val; T[v1].add %= mod;
T[v1].sum += T[v1].siz * val; T[v1].sum %= mod;
}
else if(c == '-') {
scanf("%lld%lld", &u2, &v2);
cut(u1, v1);
link(u2, v2);
}
else if(c == '/') {
split(u1, v1);
printf("%d\n",T[v1].sum%mod);
}
else {
scanf("%lld",&val);
split(u1, v1);
T[v1].val *= val; T[v1].val %= mod;
T[v1].sum *= val; T[v1].siz %= mod;
T[v1].add *= val; T[v1].add %= mod;
T[v1].mul *= val; T[v1].mul %= mod;
}
}
return ;
}
洛谷P1501 [国家集训队]Tree II(LCT)的更多相关文章
- 洛谷 P1501 [国家集训队]Tree II 解题报告
P1501 [国家集训队]Tree II 题目描述 一棵\(n\)个点的树,每个点的初始权值为\(1\).对于这棵树有\(q\)个操作,每个操作为以下四种操作之一: + u v c:将\(u\)到\( ...
- 洛谷P1501 [国家集训队]Tree II(LCT,Splay)
洛谷题目传送门 关于LCT的其它问题可以参考一下我的LCT总结 一道LCT很好的练习放懒标记技巧的题目. 一开始看到又做加法又做乘法的时候我是有点mengbi的. 然后我想起了模板线段树2...... ...
- 洛谷P1501 [国家集训队]Tree II(打标记lct)
题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...
- [洛谷P1501] [国家集训队]Tree II(LCT模板)
传送门 这是一道LCT的板子题,说白了就是在LCT上支持线段树2的操作. 所以我只是来存一个板子,并不会讲什么(再说我也不会,只能误人子弟2333). 不过代码里的注释可以参考一下. Code #in ...
- 洛谷.1501.[国家集训队]Tree II(LCT)
题目链接 日常zz被define里没取模坑 //标记下放同线段树 注意51061^2 > 2147483647,要开unsigned int //*sz[]别忘了.. #include < ...
- 【刷题】洛谷 P1501 [国家集训队]Tree II
题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...
- [洛谷P1501][国家集训队]Tree II
题目大意:给一棵树,有四种操作: $+\;u\;v\;c:$将路径$u->v$区间加$c$ $-\;u_1\;v_1\;u_2\;v_2:$将边$u_1-v_1$切断,改成边$u_2-v_2$, ...
- 洛谷 P1501 [国家集训队]Tree II
看来这个LCT板子并没有什么问题 #include<cstdio> #include<algorithm> using namespace std; typedef long ...
- 洛谷 P1501 [国家集训队]Tree II Link-Cut-Tree
Code: #include <cstdio> #include <algorithm> #include <cstring> #include <strin ...
随机推荐
- Android学习笔记(4)----Rendering Problems(The graphics preview in the layout editor may not be accurate)
在Android Studio中新建了一个 setting.xml 文件,布局好文件后,从 Text 界面切换到 Design 界面,显示了如下错误: 网上搜寻 The graphics previe ...
- MyEclipse 2017/2018 安装与破解 图文教程
SSM 框架-02-MyEclipse 2017/2018 安装与破解 现在在学J2EE,然后使用的工具就是 MyEclipse,现在就抛弃 Eclipse 了,我就不多说它俩的区别了,但是 MyEc ...
- Nginx采用yum安装方式及安装后的目录
第一次写博客就不讲究格式了,纯文字了吧 开始 第一步先执行 rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release- ...
- ElasticSearch初体验之使用
好久没写博文了, 最近项目中使用到了ElaticSearch相关的一些内容, 刚好自己也来做个总结.现在自己也只能算得上入门, 总结下自己在工作中使用Java操作ES的一些小经验吧. 本文总共分为三个 ...
- js重名的处理
### 关于重名的处理 > 在变量提升阶段,如果名字重复了,不会重新的进行声明,但是会重新的进行定义(后面赋的值会把前面赋的值给替换掉) ```javascript //=>变量提升:fn ...
- android 实现微信分享多张图片的功能
昨天公司老大通知客户改需求了,原来的微信分享改成分享多张图片,然后屁颠屁颠跑到微信平台看了以后 心里千万只草泥马狂奔而过,微信平台没有提供分享多张的SDK有木有啊,我们只能自己调用系统自带的分享功能实 ...
- JS字面量创建方式的优缺点
http://www.cnblogs.com/wuyaxing/p/6416441.html
- SQLServer数据库执行较大的脚本
当我们需要在SQLServer数据库里面执行一个比较大的文件(比如2GB)时,会发现数据库根本无法打开该脚本文件,原因是因为查询分析器只能执行100M以内的文件,所以脚本过大就会造成内存溢出.下面是具 ...
- SQL点点滴滴_查看所有存储过程或视图的位置及内容
代码:select a.name,a.[type],b.[definition] from sys.all_objects a,sys.sql_modules b where a.is_ms_ship ...
- Windows事件--重复事件检测
监视器--Windows事件--重复事件检测--计时器重置: 自动重置计时器:指定等待时间10分钟,则在10分钟后自动关闭该警报,更改状态为 正常(绿色) 检测事件1,事件3重置计数器状态,2分钟内检 ...