洛谷 P1501 [国家集训队]Tree II Link-Cut-Tree
Code:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std; void setIO(string a)
{
freopen((a+".in").c_str(),"r",stdin);
freopen((a+".out").c_str(),"w",stdout);
} #define maxn 100009
#define ll long long
#define mod 51061 int f[maxn], ch[maxn][2],siz[maxn],tag[maxn],sta[maxn],n,m;
ll mult[maxn], add[maxn], sumv[maxn], val[maxn]; int lson(int x)
{
return ch[x][0];
}
int rson(int x)
{
return ch[x][1];
}
int get(int x)
{
return ch[f[x]][1]==x;
}
int isRoot(int x)
{
return !(ch[f[x]][1]==x||ch[f[x]][0]==x);
}
void mark(int x)
{
if(!x)return;
swap(ch[x][0], ch[x][1]), tag[x]^=1;
} void pushdown(int x){
// if(!x)return;
if(mult[x]!=1)
{
if(lson(x))
{
sumv[lson(x)]*=mult[x];
mult[lson(x)]*=mult[x];
add[lson(x)]*=mult[x];
val[lson(x)]*=mult[x]; add[lson(x)]%=mod;
mult[lson(x)]%=mod;
sumv[lson(x)]%=mod;
val[lson(x)]%=mod;
}
if(rson(x))
{
sumv[rson(x)]*=mult[x];
mult[rson(x)]*=mult[x];
add[rson(x)]*=mult[x];
val[rson(x)]*=mult[x]; add[rson(x)]%=mod;
mult[rson(x)]%=mod;
sumv[rson(x)]%=mod;
val[rson(x)]%=mod;
}
mult[x]=1;
}
if(add[x])
{
if(lson(x))
{
sumv[lson(x)]+=add[x]*siz[lson(x)];
add[lson(x)]+=add[x];
val[lson(x)]+=add[x]; add[lson(x)]%=mod;
sumv[lson(x)]%=mod;
val[lson(x)]%=mod;
}
if(rson(x))
{
sumv[rson(x)]+=add[x]*siz[rson(x)];
add[rson(x)]+=add[x];
val[rson(x)]+=add[x]; add[rson(x)]%=mod;
sumv[rson(x)]%=mod;
val[rson(x)]%=mod;
}
add[x]=0;
}
if(tag[x]) mark(ch[x][0]), mark(ch[x][1]), tag[x]=0;
} void pushup(int x)
{
if(!x)return;
siz[x]=siz[lson(x)]+siz[rson(x)]+1;
sumv[x]=(sumv[lson(x)]+sumv[rson(x)]+val[x])%mod;
} void rotate(int o){
int old=f[o],fold=f[old],which=get(o);
if(!isRoot(old)) ch[fold][ch[fold][1]==old]=o;
f[o]=fold;
ch[old][which]=ch[o][which^1], f[ch[old][which]]=old;
ch[o][which^1]=old,f[old]=o;
pushup(old),pushup(o),pushup(fold);
}
void splay(int x){
int v=0,u=x;
sta[++v]=u;
while(!isRoot(u)) sta[++v]=f[u],u=f[u];
while(v) pushdown(sta[v--]);
u=f[u];
for(int fa;(fa=f[x])!=u;rotate(x))
if(f[fa]!=u) rotate(get(x)==get(fa)?fa:x);
}
void Access(int x)
{
for(int y=0;x;y=x,x=f[x]) splay(x), ch[x][1]=y, pushup(x);
}
void makeRoot(int x)
{
Access(x), splay(x),mark(x);
}
void split(int x,int y)
{
makeRoot(x), Access(y), splay(y);
}
void Link(int x,int y)
{
makeRoot(x), f[x]=y;
}
void cut(int x,int y)
{
makeRoot(x), Access(y), splay(y);
f[x] = ch[y][0] = 0, pushup(y);
} void debug(){ for(int i=1;i<=n;++i) printf("%d %lld\n",siz[i],sumv[i]); } int main(){
//setIO("input");
memset(add,0,sizeof(add)), memset(mult,1,sizeof(mult));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) sumv[i]=val[i]=1;
for(int i=1;i<n;++i)
{
int a,b;
scanf("%d%d",&a,&b);
Link(a,b);
} for(int i=1;i<=m;++i)
{
char opt[10];
int a,b,c,d;
scanf("%s",opt);
if(opt[0]=='+')
{
scanf("%d%d%d",&a,&b,&c);
split(a,b);
sumv[b]+=siz[b]*c;
add[b]+=c;
val[b]+=c; sumv[b]%=mod;
add[b]%=mod;
val[b]%=mod;
}
if(opt[0]=='-')
{
scanf("%d%d%d%d",&a,&b,&c,&d);
cut(a,b);
Link(c,d);
}
if(opt[0]=='*')
{
scanf("%d%d%d",&a,&b,&c);
split(a,b);
sumv[b]*=c;
add[b]*=c;
mult[b]*=c;
val[b]*=c; sumv[b]%=mod;
add[b]%=mod;
mult[b]%=mod;
val[b]%=mod;
}
if(opt[0]=='/')
{
scanf("%d%d",&a,&b);
split(a,b);
printf("%lld\n",sumv[b]%mod);
}
}
return 0;
}
洛谷 P1501 [国家集训队]Tree II Link-Cut-Tree的更多相关文章
- 洛谷 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
题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...
- 洛谷P1501 [国家集训队]Tree II(LCT)
题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...
- 洛谷P1501 [国家集训队]Tree II(打标记lct)
题目描述 一棵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(LCT模板)
传送门 这是一道LCT的板子题,说白了就是在LCT上支持线段树2的操作. 所以我只是来存一个板子,并不会讲什么(再说我也不会,只能误人子弟2333). 不过代码里的注释可以参考一下. Code #in ...
- 【洛谷 P3690】 【模板】Link Cut Tree (动态树)
题目链接 \(RT\). FlashHu巨佬的博客 #include <cstdio> #define R register int #define I inline void #defi ...
随机推荐
- IntelliJ IDEA中JAVA连接MYSQL
1.下载mysql包 2.项目中引入mysql包 3.连接数据库,查询结果 看jdbc数据库连接类 package Facade; import java.sql.*; /** * Created b ...
- mybatis使用注解替代xml配置,动态生成Sql
mybatis使用注解替代xml配置时,遇到判断条件是否为null或者为空时,@Select很难搞定,不知道怎么办? mybatis3中增加了使用注解来配置Mapper的新特性,使用 SelectPr ...
- 新型查询系统impala
这羊头很酷... Apache Impala是Apache Hadoop的开源本地分析数据库.Impala由Cloudera,MapR,Oracle和Amazon提供. 在Hadoop上进行BI风格的 ...
- Android TextView加上阴影效果
<TextView android:id="@+id/test_shadow" android:layout_width="wrap_content" a ...
- hadoop 编译自己的jar包并运行
我修从网上找了份java代码 我为了让它在hadoop下跑起来居然花了两个多小时... 首先最好不要在java代码中设置package...使用default package即可... 然后在java ...
- Twilio介绍和使用
1.Twilio是?需要如何才能通过Twilio打国际网络电话 http://uuxn.com/twilio-toll-free-sms介绍了通过网页来收取和发送信息 需求:通过TWILIO拨打国外座 ...
- sublime text3前端常用插件
安装Package Control 在安装插件之前,需要让sublime安装Package Control.打开Sublime Text的控制台,快捷键ctrl + ~,在控制台中输入以下代码. im ...
- swfit的特点
swfit的特点: 1.swift句尾不需要分号,除非你想在一行中写三行代码就加分号隔开. 2.swift不要写main函数,程序默认从上往下执行 3.swift不分.h和.m文件,一个类只有.swi ...
- 3ds Max修改桌面快捷方式为中文语言
通过上篇教程的学习,我们已经会切换3ds Max 2018的界面语言了,相关内容可参阅3ds Max如何设置中文界面.但是如果每次都要从开始菜单进行操作,岂不麻烦?简单一点,可以在桌面添加3ds Ma ...
- 前端压缩图片,前端压缩图片后转换为base64.
今天利用一上午研究了一下前端如何将5m左右的照片转换base64大小为 100k以内! 有两个链接:https://www.cnblogs.com/007sx/p/7583202.html :http ...