题目链接

日常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)的更多相关文章

  1. 洛谷P1501 [国家集训队]Tree II(LCT)

    题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...

  2. 洛谷 1501 [国家集训队]Tree II BZOJ 2631 Tree

    [题解] 维护乘法标记和加法标记的LCT #include<cstdio> #include<algorithm> #define Mod (51061) #define N ...

  3. 洛谷 P1501 [国家集训队]Tree II 解题报告

    P1501 [国家集训队]Tree II 题目描述 一棵\(n\)个点的树,每个点的初始权值为\(1\).对于这棵树有\(q\)个操作,每个操作为以下四种操作之一: + u v c:将\(u\)到\( ...

  4. 洛谷P1501 [国家集训队]Tree II(LCT,Splay)

    洛谷题目传送门 关于LCT的其它问题可以参考一下我的LCT总结 一道LCT很好的练习放懒标记技巧的题目. 一开始看到又做加法又做乘法的时候我是有点mengbi的. 然后我想起了模板线段树2...... ...

  5. 洛谷P1501 [国家集训队]Tree II(打标记lct)

    题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...

  6. [洛谷P1501] [国家集训队]Tree II(LCT模板)

    传送门 这是一道LCT的板子题,说白了就是在LCT上支持线段树2的操作. 所以我只是来存一个板子,并不会讲什么(再说我也不会,只能误人子弟2333). 不过代码里的注释可以参考一下. Code #in ...

  7. 【刷题】洛谷 P1501 [国家集训队]Tree II

    题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...

  8. [洛谷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$, ...

  9. 洛谷 P1501 [国家集训队]Tree II

    看来这个LCT板子并没有什么问题 #include<cstdio> #include<algorithm> using namespace std; typedef long ...

随机推荐

  1. Linux内存管理--基本概念【转】

    转自:http://blog.csdn.net/myarrow/article/details/8624687 1. Linux物理内存三级架构 对于内存管理,Linux采用了与具体体系架构不相关的设 ...

  2. 董事局主席董事长总裁首席执行官CEO总裁董事监事区别

    董事长是公司的最大股东:董事长是董事会的主席,一般是企业的所有者,掌握企业的股权并且决定企业的发展策略. 董事局主席通常是在大财团中才会出现,董事局主席管数个董事长,一个大财团涉及很多方面的业务,因此 ...

  3. 一个有趣的小例子,带你入门协程模块-asyncio

    一个有趣的小例子,带你入门协程模块-asyncio 上篇文章写了关于yield from的用法,简单的了解异步模式,[https://www.cnblogs.com/c-x-a/p/10106031. ...

  4. Project Euler Problem8

    Largest product in a series Problem 8 Find the greatest product of five consecutive digits in the 10 ...

  5. WDS 三种模式

    (1)懒人模式(Lazy mode) 此模式下不需要填写对端的BSSID,本端AP的WDS连接作为被动连接,只需要对端填写了本端AP的BSSID即可,效果和桥接模式一样. (2)桥接模式(Bridge ...

  6. Go语言规格说明书 之 结构体类型(Struct types)

    go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...

  7. PYTHON-基本数据类型-元祖类型,字典类型,集合类型-练习

    # 1 有如下值集合 [11,22,33,44,55,66,77,88,99,90...],# 将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中## 即: ...

  8. PYTHON-基本数据类型-数字类型,字符串类型,列表类型-练习

    # 字符串练习# 写代码,有如下变量,请按照要求实现每个功能 (共6分,每小题各0.5分)# name = " aleX"# # 1) 移除 name 变量对应的值两边的空格,并输 ...

  9. poj2352树状数组解决偏序问题

    树状数组解决这种偏序问题是很厉害的! /* 输入按照y递增,对于第i颗星星,它的level就是之前出现过的星星中,横坐标小于i的总数 */ #include<iostream> #incl ...

  10. cf1061D 贪心+multiset 好题!

    cf上的思维题真好! 本题是在模拟的基础上贪心即可:将n段时间按照左端点(右端点为第二关键字)从小到大排序,然后遍历每一个时间段. 对于每一个时间段[li,ri],先找到multiset中最靠近li但 ...