洛谷.1501.[国家集训队]Tree II(LCT)
日常zz被define里没取模坑
//标记下放同线段树 注意51061^2 > 2147483647,要开unsigned int
//*sz[]别忘了。。
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define mod (51061)
typedef unsigned int uint;
const int N=1e5+5;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
namespace LCT
{
#define lson son[x][0]
#define rson son[x][1]
#define ADD(x,v) (x)+=(v), (x)%=mod//直接这样最快
// #define ADD(x,v) (x)+=(v), (x)>=mod?(x)-=mod:0
// #define ADD(x,v) (x)+=(v); if((x)>=mod) (x)-=mod//比上一行快一点
int son[N][2],fa[N],sk[N],sz[N];
uint val[N],sum[N],m_tag[N],a_tag[N];
bool r_tag[N];
inline void Update(int x){
sz[x]=sz[lson]+sz[rson]+1;
sum[x]=(sum[lson]+sum[rson]+val[x])%mod;
}
inline void Rev(int x){
std::swap(lson,rson), r_tag[x]^=1;
}
inline void Mult(int x,uint v){
(sum[x]*=v)%=mod, (val[x]*=v)%=mod, (m_tag[x]*=v)%=mod, (a_tag[x]*=v)%=mod;
}
inline void Add(int x,uint v){
// sum[x]+=v*sz[x]%mod, sum[x]>=mod?sum[x]-=mod:0, val[x]+=v, val[x]>=mod?val[x]-=mod:0, a_tag[x]+=v, a_tag[x]>=mod?a_tag[x]-=mod:0;
// ADD(sum[x],v*sz[x]%mod/*2.3 ADD这要取模!*/); ADD(val[x],v); ADD(a_tag[x],v);
ADD(sum[x],v*sz[x]); ADD(val[x],v); ADD(a_tag[x],v);
}
void PushDown(int x){
if(m_tag[x]!=1) Mult(lson,m_tag[x]),Mult(rson,m_tag[x]),m_tag[x]=1;
if(a_tag[x]) Add(lson,a_tag[x]),Add(rson,a_tag[x]),a_tag[x]=0;
if(r_tag[x]) Rev(lson),Rev(rson),r_tag[x]=0;
}
inline bool n_root(int x){
return son[fa[x]][0]==x||son[fa[x]][1]==x;
}
void Rotate(int x)
{
int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
if(n_root(a)) son[b][son[b][1]==a]=x;
if(son[x][r]) fa[son[x][r]]=a;
fa[a]=x, fa[x]=b, son[a][l]=son[x][r], son[x][r]=a;
Update(a);
}
void Splay(int x)
{
int t=1,a=x,b; sk[1]=x;
while(n_root(a)) sk[++t]=a=fa[a];
while(t) PushDown(sk[t--]);
while(n_root(x))
{
a=fa[x],b=fa[a];
if(n_root(a)) Rotate(son[a][1]==x^son[b][1]==a?x:a);
Rotate(x);
}
Update(x);
}
void Access(int x){
for(int pre=0; x; x=fa[pre=x])
Splay(x), rson=pre, Update(x);
}
void Make_root(int x){
Access(x), Splay(x), Rev(x);
}
void Split(int x,int y){
Make_root(x), Access(y), Splay(y);
}
// int Find_root(int x){
// Access(x), Splay(x);
// while(lson) x=lson;
// return x;
// }
void Link(int x,int y){
Make_root(x), fa[x]=y;
}
void Cut(int x,int y){
Split(x,y), fa[x]=son[y][0]=0, Update(y);
// Make_root(x);
// if(Find_root(y)==x&&fa[x]==y&&!rson)
// fa[x]=son[y][0]=0, Update(y);
}
}
int main()
{
int n=read(),q=read();
for(int i=1; i<=n; ++i) LCT::sz[i]=LCT::sum[i]=LCT::val[i]=LCT::m_tag[i]=1;
for(int u,v,i=1; i<n; ++i) u=read(),v=read(),LCT::Link(u,v);
int u,v,c,d; char opt[3];
while(q--)
{
scanf("%s",opt),u=read(),v=read();
if(opt[0]=='+') c=read(),LCT::Split(u,v),LCT::Add(v,c);
else if(opt[0]=='-') c=read(),d=read(),LCT::Cut(u,v),LCT::Link(c,d);
else if(opt[0]=='*') c=read(),LCT::Split(u,v),LCT::Mult(v,c);
else LCT::Split(u,v),printf("%d\n",LCT::sum[v]);
}
return 0;
}
洛谷.1501.[国家集训队]Tree II(LCT)的更多相关文章
- 洛谷P1501 [国家集训队]Tree II(LCT)
题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...
- 洛谷 1501 [国家集训队]Tree II BZOJ 2631 Tree
[题解] 维护乘法标记和加法标记的LCT #include<cstdio> #include<algorithm> #define Mod (51061) #define N ...
- 洛谷 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 ...
- 【刷题】洛谷 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 ...
随机推荐
- 【黑客免杀攻防】读书笔记6 - PE文件知识在免杀中的应用
0x1 PE文件与免杀思路 基于PE文件结构知识的免杀技术主要用于对抗启发式扫描. 通过修改PE文件中的一些关键点来达到欺骗反病毒软件的目的. 修改区段名 1.1 移动PE文件头位置免杀 工具:PeC ...
- Linux内核驱动之GPIO子系统(一)GPIO的使用【转】
转自:http://blog.csdn.net/tommy_wxie/article/details/9427047 一 概述 Linux内核中gpio是最简单,最常用的资源(和 interrupt ...
- gpio_request 原形代码【转】
转自:http://blog.csdn.net/maopig/article/details/7428561 其原型为 int gpio_request(unsigned gpio, const ch ...
- html的结构-厂子型的布局
上图所示的布局设计是很常见的.这个该怎么做呢? 技术需求:header 要固定住在顶部,不随鼠标滚动而向上移动:左边的div的有一定的宽度,但是要贴浏览器的底部(屏幕顶部):右边的dv要占据右边的全屏 ...
- Android service与Thread
很多时候,你可能会问,为什么要用 Service,而不用 Thread 呢,因为用 Thread 是很方便的,比起 Service 也方便多了,下面我详细的来解释一下. 1). Thread:Thre ...
- centos7 部署 open-falcon 0.2.1
=============================================== 2019/4/28_第1次修改 ccb_warlock 更新 ...
- 通过Cookie跳过登录验证码【限cookie不失效有用】
验证码,相信每个写web自动化测试的同学来说,都是个头疼的事,怎么办呢? 方法还是有的,先说今天这种方式,通过cookie绕过登录验证码 思路: 需要你通过抓包工具抓到你登录的cookie 接下来开始 ...
- Python-CSS高级 题目
一.简答1.完整总结display三种基础显示方式的显示方式与嵌套规则 /* inline */ /*1.同行显示, 就相当于纯文本, 当一行显示不下, 如就是一个字显示不下,那么显示不下的那一个字就 ...
- php和NodeJs共存的开发环境
1 折腾 php nodejs 到一起 nodejs当然很火,就像着火了一样,但是必须承认要搭建一个前端的demo开发环境还是PHP靠谱, windows下可以非常的集成套件,比如http://www ...
- laravel 同数据表字段比较查询和状态不正规排序
今天写群组推荐接口,要求未满的群 ( 群最大人数字段maxusers, 群人数字段affiliations_count 都在群组表中),官方,热门(普通群0 ,官方1,热门2 ) 排序的群 同表字段比 ...