洛谷 P1501 [国家集训队]Tree II 解题报告
P1501 [国家集训队]Tree II
题目描述
一棵\(n\)个点的树,每个点的初始权值为\(1\)。对于这棵树有\(q\)个操作,每个操作为以下四种操作之一:
+ u v c
:将\(u\)到\(v\)的路径上的点的权值都加上自然数\(c\);- u1 v1 u2 v2
:将树中原有的边\((u_1,v_1)\)删除,加入一条新边\((u_2,v_2)\),保证操作完之后仍然是一棵树;* 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\)
就是个LCTsb题
然后我放乘法标记的时候忘记放到加法标记上了,记录一下自己的sb错误。
注意要开uint
Code:
#include <cstdio>
#define ls ch[now][0]
#define rs ch[now][1]
#define fa par[now]
const unsigned int mod=51061;
const unsigned int N=1e5+10;
unsigned int ch[N][2],par[N],sum[N],dat[N],tag[N],add[N],mul[N],siz[N],s[N],tot,tmp,n,m;
bool isroot(int now){return ch[fa][0]==now||ch[fa][1]==now;}
unsigned int identity(int now){return ch[fa][1]==now;}
void connect(int f,int now,int typ){ch[f][typ]=now,fa=f;}
void Reverse(int now){tag[now]^=1,tmp=ls,ls=rs,rs=tmp;}
void updata(int now){sum[now]=(sum[ls]+sum[rs]+dat[now])%mod;siz[now]=siz[ls]+siz[rs]+1;}
void pushdown(int now)
{
if(tag[now]){if(ls) Reverse(ls);if(rs) Reverse(rs);tag[now]^=1;}
if(ls)
{
sum[ls]=(sum[ls]*mul[now]+add[now]*siz[ls])%mod;
dat[ls]=(dat[ls]*mul[now]+add[now])%mod;
mul[ls]=mul[ls]*mul[now]%mod;
add[ls]=(add[ls]*mul[now]+add[now])%mod;
}
if(rs)
{
sum[rs]=(sum[rs]*mul[now]+add[now]*siz[rs])%mod;
dat[rs]=(dat[rs]*mul[now]+add[now])%mod;
mul[rs]=mul[rs]*mul[now]%mod;
add[rs]=(add[rs]*mul[now]+add[now])%mod;
}
add[now]=0,mul[now]=1;
}
void Rotate(int now)
{
int p=fa,typ=identity(now);
connect(p,ch[now][typ^1],typ);
if(isroot(p)) connect(par[p],now,identity(p));
else fa=par[p];
connect(now,p,typ^1);
updata(p),updata(now);
}
void splay(int now)
{
while(isroot(now)) s[++tot]=now,now=fa;
s[++tot]=now;
while(tot) pushdown(s[tot--]);
now=s[1];
for(;isroot(now);Rotate(now))
if(isroot(fa))
Rotate(identity(now)^identity(fa)?now:fa);
}
void access(int now)
{
for(int las=0;now;las=now,now=fa)
splay(now),rs=las,updata(now);
}
void evert(int now){access(now),splay(now),Reverse(now);}
void link(int u,int v){evert(u),par[u]=v;}
void makeline(int u,int v){evert(u),access(v),splay(v);}
void cat(int u,int v){makeline(u,v),ch[v][0]=par[u]=0,updata(v);}
unsigned int query(int u,int v){makeline(u,v);return sum[v];}
void Add(int u,int v,unsigned int d)
{
makeline(u,v);
(dat[v]+=d)%=mod,(sum[v]+=d*siz[v])%=mod,(add[v]+=d)%=mod;
}
void Mul(int u,int v,unsigned int d)
{
makeline(u,v);
(dat[v]*=d)%=mod,(sum[v]*=d)%=mod,(add[v]*=d)%=mod,(mul[v]*=d)%=mod;
}
int main()
{
scanf("%d%d",&n,&m);
for(unsigned int i=1;i<=n;i++) siz[i]=dat[i]=sum[i]=mul[i]=1;
for(unsigned int u,v,i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
link(u,v);
}
char op[3];
for(unsigned int u,v,c,i=1;i<=m;i++)
{
scanf("%s%d%d",op,&u,&v);
if(op[0]=='+') scanf("%d",&c),Add(u,v,c);
else if(op[0]=='-') cat(u,v),scanf("%d%d",&u,&v),link(u,v);
else if(op[0]=='*') scanf("%d",&c),Mul(u,v,c);
else printf("%d\n",query(u,v));
}
return 0;
}
2018.12.7
洛谷 P1501 [国家集训队]Tree II 解题报告的更多相关文章
- 洛谷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 Link-Cut-Tree
Code: #include <cstdio> #include <algorithm> #include <cstring> #include <strin ...
- [洛谷P1501] [国家集训队]Tree II(LCT模板)
传送门 这是一道LCT的板子题,说白了就是在LCT上支持线段树2的操作. 所以我只是来存一个板子,并不会讲什么(再说我也不会,只能误人子弟2333). 不过代码里的注释可以参考一下. Code #in ...
- 洛谷 P1852 [国家集训队]跳跳棋 解题报告
P1852 [国家集训队]跳跳棋 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在\(a\),\(b\), ...
随机推荐
- scikit-learn API
scikit-learn API 这是scikit-learn的类和函数参考.有关详细信息,请参阅完整的用户指南,因为类和功能原始规格可能不足以提供有关其用途的完整指南. sklearn.base:基 ...
- ABP 框架集成EF批量增加、删除、修改只针对使用mmsql的
AppService 层使用nuget 添加 EFCore.BulkExtensions 引用 using Abp.Application.Services.Dto; using Abp.Domain ...
- git拉代码,IntelliJ idea报错,cannot load module xxxxx
1 从git上下工程的时候,IntelliJ idea报错,cannot load module xxxx VCS-git-clone-ssh:xxxx ,报错cannot load module x ...
- 在jre1.8版本下,使用ikvm将jar转换为dll,以供c#调用
由于合作方使用.net编程,jar包不能用,需要转换成dll格式,来回转换了十几个dll文件(心塞..),终于生成了一个可用的.在这里将走过的弯弯绕绕总结下,希望遇到相似问题的同好们,能走得顺利些. ...
- NO.1:自学python之路------Hello world、判断、循环
引言 人工智能如今越来越贴近生活,在这里将记录我自学python与tensorflow的过程.编程使用IDE:visual studio 2017,python版本3.6.4,tensorflow版本 ...
- 自然语言处理 - 如何通俗地理解TFIDF?
本博客属个人学习笔记,如有疏漏,欢迎在评论留言指出~转载请注明. 在自然语言处理中,TFIDF常常被人提及.很多材料都提及TFIDF中的“普遍重要性”,但很少有材料去简单解释其中的原理.TFIDF其实 ...
- [转]如何设计自适应屏幕大小的网页 Responsive Web Design
随着3G的普及,越来越多的人使用手机上网. 移动设备正超过桌面设备,成为访问互联网的最常见终端.于是,网页设计师不得不面对一个难题:如何才能在不同大小的设备上呈现同样的网页? 手机的屏幕比较小,宽度通 ...
- 华为中兴借eBay出海 靠零售渠道撬动市场
在跨境电商领域,大多数中国商家依靠“中国制造”的优势和价格战策略打拼出一条血路,在海外市场占领了自己的一席 之地.不过,山寨货纷纷出海的同时,中国本土的品牌商们也开始了探索海外市场之旅.目前,华为.中 ...
- 第七次ScrumMeeting博客
第七次ScrumMeeting博客 本次会议于11月1日(三)22时整在3公寓725房间召开,持续15分钟. 与会人员:刘畅.辛德泰.窦鑫泽.张安澜.赵奕.方科栋. 1. 每个人的工作(有Issue的 ...
- GCD最大公约数
说明: 最初跟鹏哥学习最大公约数的算法是辗转相除,确实印象很深刻,那种辗转赋值的思想在好多题目中都有运用,但随着进一步学习,我也参考了其他几种方便快捷的最大公约数求法,在这里做一个总结. . int ...