lct裸题

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
int n, m, uu, vv, val[100005], tagm[100005], taga[100005], sum[100005], siz[100005];
int rev[100005], ww, xx, ch[100005][2], fa[100005];
char ss[15];
const int mod=51061;
bool isRoot(int x){
return ch[fa[x]][0]!=x && ch[fa[x]][1]!=x;
}
bool getW(int x){
return ch[fa[x]][1]==x;
}
void pushMul(int x, int k){
sum[x] = (ll)sum[x] * k % mod;
val[x] = (ll)val[x] * k % mod;
tagm[x] = (ll)tagm[x] * k % mod;
taga[x] = (ll)taga[x] * k % mod;
}
void pushAdd(int x, int k){
sum[x] = (sum[x] + (ll)siz[x]*k) % mod;
val[x] = (val[x] + k) % mod;
taga[x] = (taga[x] + k) % mod;
}
void pushDown(int x){
if(tagm[x]!=1){
pushMul(ch[x][0], tagm[x]);
pushMul(ch[x][1], tagm[x]);
tagm[x] = 1;
}
if(tagm[x]){
pushAdd(ch[x][0], taga[x]);
pushAdd(ch[x][1], taga[x]);
taga[x] = 0;
}
if(rev[x]){
swap(ch[x][0], ch[x][1]);
rev[ch[x][0]] ^= 1;
rev[ch[x][1]] ^= 1;
rev[x] = 0;
}
}
void xf(int x){
if(!isRoot(x)) xf(fa[x]);
pushDown(x);
}
void upd(int x){
siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;
sum[x] = (sum[ch[x][0]] + sum[ch[x][1]] + val[x]) % mod;
}
void rotate(int x){
int old=fa[x], oldf=fa[old], w=getW(x);
if(!isRoot(old)) ch[oldf][ch[oldf][1]==old] = x;
ch[old][w] = ch[x][w^1]; ch[x][w^1] = old;
fa[ch[old][w]] = old; fa[ch[x][w^1]] = x; fa[x] = oldf;
upd(old); upd(x);
}
void splay(int x){
xf(x);
while(!isRoot(x)){
int f=fa[x];
if(!isRoot(f)) rotate(getW(f)==getW(x)?f:x);
rotate(x);
}
}
void access(int x){
int y=0;
while(x){
splay(x);
ch[x][1] = y;
upd(x);
y = x;
x = fa[x];
}
}
void makeRoot(int x){
access(x);
splay(x);
rev[x] ^= 1;
}
void link(int u, int v){
makeRoot(u);
fa[u] = v;
}
void splitLine(int u, int v){
makeRoot(u);
access(v);
splay(v);
}
void cut(int u, int v){
splitLine(u, v);
ch[v][0] = fa[u] = 0;
}
int main(){
cin>>n>>m;
for(int i=1; i<=n; i++)
tagm[i] = val[i] = siz[i] = 1;
for(int i=1; i<n; i++){
scanf("%d %d", &uu, &vv);
link(uu, vv);
}
while(m--){
scanf("%s", ss);
if(ss[0]=='+'){
scanf("%d %d %d", &uu, &vv, &ww);
splitLine(uu, vv);
pushAdd(vv, ww);
}
else if(ss[0]=='-'){
scanf("%d %d %d %d", &uu, &vv, &ww, &xx);
cut(uu, vv);
link(ww, xx);
}
else if(ss[0]=='*'){
scanf("%d %d %d", &uu, &vv, &ww);
splitLine(uu, vv);
pushMul(vv, ww);
}
else{
scanf("%d %d", &uu, &vv);
splitLine(uu, vv);
printf("%d\n", sum[vv]);
}
}
return 0;
}

luogu1501 [国家集训队]Tree II的更多相关文章

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

    P1501 [国家集训队]Tree II 看着维护吧2333333 操作和维护区间加.乘线段树挺像的 进行修改操作时不要忘记吧每个点的点权$v[i]$也处理掉 还有就是$51061^2=2607225 ...

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

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

  3. [国家集训队]Tree II

    嘟嘟嘟 这道题其实还是挺基础的,只不过操作有点多. 区间乘和区间加按线段树的方式想. 那么就先要下放乘标记,再下放加标记.但这两个和反转标记是没有先后顺序的. 对于区间加,sum加的是区间长度\(*\ ...

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

    题目链接 Tree Ⅱ\(=\)[模板]LCT+[模板]线段树2.. 分别维护3个标记,乘的时候要把加法标记也乘上. 还有就是模数的平方刚好爆\(int\),所以开昂赛德\(int\)就可以了. 我把 ...

  5. 【洛谷1501】[国家集训队] Tree II(LCT维护懒惰标记)

    点此看题面 大致题意: 有一棵初始边权全为\(1\)的树,四种操作:将两点间路径边权都加上一个数,删一条边.加一条新边,将两点间路径边权都加上一个数,询问两点间路径权值和. 序列版 这道题有一个序列版 ...

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

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

  7. 洛谷.1501.[国家集训队]Tree II(LCT)

    题目链接 日常zz被define里没取模坑 //标记下放同线段树 注意51061^2 > 2147483647,要开unsigned int //*sz[]别忘了.. #include < ...

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

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

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

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

随机推荐

  1. go实现主线程等待子线程都运行完再退出

    方式一 package main import ( "fmt" ) func main() { ch := make(chan struct{}) count := 2 // co ...

  2. 关于Kettle的事务和转换内步骤的顺序执行

    关于Kettle的事务和转换内步骤的顺序执行 近来有项目中遇到Kettle事务处理和转换内步骤顺序执行的问题.为此进行了研究,找到了一个解决办法. 在Kettle中,一个Job内的转换,缺省是顺序执行 ...

  3. bootstrap fileinput 上传文件

    最近用到文件上传功能, 说实话:以前遇到过一次,COPY了别人的代码 结束! 这次又要用,可是看到别人很酷的文件上传功能,心痒了! 好吧.简单的办法,找控件: bootstrap fileinput ...

  4. mysql-新增、更新、删除语句

    1.插入数据: INSERT INTO t_book VALUES(NULL,'我爱我家',20,'张三',1); INSERT INTO t_book(id,bookName,price,autho ...

  5. UVA 624 CD(01背包,要记录路径)

    题意: 有n张CD(n<=20),每张能播放的时长不同.给定一个时长限制t,挑出部分的CD使得总播放时间最长.顺便输出路径! 思路: 重点在输出路径,否则这题很普通.那就要用二维数组记录每个CD ...

  6. 使用JS的画布制作一个瞄准镜

    <canvas width="600" height="500" id="myCanvas"></canvas> & ...

  7. Codeforces Round #321 (Div. 2) C Kefa and Park(深搜)

    dfs一遍,维护当前连续遇到的喵的数量,然后剪枝,每个统计孩子数量判断是不是叶子结点. #include<bits/stdc++.h> using namespace std; ; int ...

  8. Array - Container With Most Water

    /** * 此为暴力解法 * Find two lines, which together with x-axis forms a container, such that the container ...

  9. 字符编码:Unicode和UTF-8的关系

    今天中午,我突然想搞清楚Unicode和UTF-8之间的关系,于是就开始在网上查资料. 结果,这个问题比我想象的复杂,从午饭后一直看到晚上9点,才算初步搞清楚. 下面就是我的笔记,主要用来整理自己的思 ...

  10. C++容器类-list

    C++ 表(List容器类) 一.概念 头文件:#include <list> 又叫链表,是一种双线性链表,只能顺序访问(从前往后或从后往前) 他不支持随机访问. 二.方法 #includ ...