嘟嘟嘟




这道题其实还是挺基础的,只不过操作有点多。




区间乘和区间加按线段树的方式想。

那么就先要下放乘标记,再下放加标记。但这两个和反转标记是没有先后顺序的。

对于区间加,sum加的是区间长度\(*\)lazy标记。但是线段树区间固定,而lct不是,所以还要单独维护一个size。

还有一点,这个是splay的性质,就是当前节点的sum还要算上自己的权值,而不像线段树完全由子树信息合并而来。

最最最后一点,得开long long,包括点权。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 1e5 + 5;
const ll mod = 51061;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
} int n, q;
char c[2];
struct Tree
{
int ch[2], fa;
int siz, rev;
ll val, sum, add, mul;
}t[maxn]; In void c_rev(int now)
{
swap(t[now].ch[0], t[now].ch[1]);
t[now].rev ^= 1;
}
In void c_mul(int now, ll lzy)
{
t[now].sum *= lzy; t[now].sum %= mod;
t[now].val *= lzy; t[now].val %= mod;
t[now].mul *= lzy; t[now].mul %= mod;
t[now].add *= lzy; t[now].add %= mod;
}
In void c_add(int now, ll lzy)
{
t[now].sum += lzy * (ll)t[now].siz; t[now].sum %= mod;
t[now].val += lzy; t[now].val %= mod;
t[now].add += lzy; t[now].add %= mod;
}
In void pushdown(int now)
{
if(t[now].rev)
{
if(t[now].ch[0]) c_rev(t[now].ch[0]);
if(t[now].ch[1]) c_rev(t[now].ch[1]);
t[now].rev = 0;
}
if(t[now].mul != 1)
{
if(t[now].ch[0]) c_mul(t[now].ch[0], t[now].mul);
if(t[now].ch[1]) c_mul(t[now].ch[1], t[now].mul);
t[now].mul = 1;
}
if(t[now].add)
{
if(t[now].ch[0]) c_add(t[now].ch[0], t[now].add);
if(t[now].ch[1]) c_add(t[now].ch[1], t[now].add);
t[now].add = 0;
}
}
In void pushup(int now)
{
t[now].siz = t[t[now].ch[0]].siz + t[t[now].ch[1]].siz + 1;
t[now].sum = (t[t[now].ch[0]].sum + t[t[now].ch[1]].sum + t[now].val) % mod;
}
In bool n_root(int now)
{
return t[t[now].fa].ch[0] == now || t[t[now].fa].ch[1] == now;
}
In void rotate(int x)
{
int y = t[x].fa, z = t[y].fa, k = (t[y].ch[1] == x);
if(n_root(y)) t[z].ch[t[z].ch[1] == y] = x; t[x].fa = z;
t[y].ch[k] = t[x].ch[k ^ 1]; t[t[y].ch[k]].fa = y;
t[x].ch[k ^ 1] = y; t[y].fa = x;
pushup(y), pushup(x);
}
int st[maxn], top = 0;
In void splay(int x)
{
int y = x;
st[top = 1] = y;
while(n_root(y)) st[++top] = y = t[y].fa;
while(top) pushdown(st[top--]);
while(n_root(x))
{
int y = t[x].fa, z = t[y].fa;
if(n_root(y)) rotate(((t[y].ch[0] == x) ^ (t[z].ch[0] == y)) ? x : y);
rotate(x);
}
}
In void access(int x)
{
int y = 0;
while(x)
{
splay(x); t[x].ch[1] = y;
pushup(x);
y = x; x = t[x].fa;
}
}
In void make_root(int x)
{
access(x); splay(x);
c_rev(x);
}
In int find_root(int x)
{
access(x); splay(x);
while(t[x].ch[0]) pushdown(x), x = t[x].ch[0];
return x;
}
In void split(int x, int y)
{
make_root(x);
access(y); splay(y);
}
In void Link(int x, int y)
{
make_root(x);
if(find_root(y) != x) t[x].fa = y;
}
In void Cut(int x, int y)
{
make_root(x);
if(find_root(y) == x && t[x].fa == y && !t[x].ch[1])
t[y].ch[0] = t[x].fa = 0, pushup(y);
} int main()
{
n = read(); q = read();
for(int i = 1; i <= n; ++i) t[i].val = t[i].mul = t[i].siz = 1;
for(int i = 1, x, y; i < n; ++i) x = read(), y = read(), Link(x, y);
for(int i = 1; i <= q; ++i)
{
scanf("%s", c); int x = read(), y = read();
if(c[0] == '+') {int d = read(); split(x, y); c_add(y, d);}
else if(c[0] == '*') {int d = read(); split(x, y); c_mul(y, d);}
else if(c[0] == '/') split(x, y), write(t[y].sum), enter;
else
{
Cut(x, y);
x = read(), y = read();
Link(x, y);
}
}
return 0;
}

[国家集训队]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. 【洛谷 P1501】 [国家集训队]Tree II(LCT)

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

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

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

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

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

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

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

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

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

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

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

  9. p1501 [国家集训队]Tree II

    传送门 分析 lct板子题 单独维护一下加和乘的情况即可 维护方法和维护翻转差不多 代码 #include<iostream> #include<cstdio> #includ ...

随机推荐

  1. Spring源码分析:非懒加载的单例Bean初始化过程(下)

    上文Spring源码分析:非懒加载的单例Bean初始化过程(上),分析了单例的Bean初始化流程,并跟踪代码进入了主流程,看到了Bean是如何被实例化出来的.先贴一下AbstractAutowireC ...

  2. SQL查询中的转义字符

    转载自http://blog.csdn.net/Adi_liu/archive/2007/12/06/1920606.aspx   如果想查找“_cs”结尾的的账户 select * from [us ...

  3. 从实例角度分析java的public、protected、private和default访问权限

    一.public 同一个package 1.本类内部 public class A { public int f=1; public void m1() {} public void m2() { f ...

  4. jQuery的$.getScript方法去加载javaScript文档解析

    1.两个文件的代码如下: <script> function Ajax(){ //将9-4.html中的Ajax()函数进行修改 $.getScript('9-8.js',function ...

  5. Code Signal_练习题_arrayMaxConsecutiveSum

    Given array of integers, find the maximal possible sum of some of its k consecutive elements. Exampl ...

  6. 使用LINQ查询数据实例和理解

    使用LINQ查询数据实例和理解 var contacts= from customer in db.Customers where customer.Name.StartsWith("A&q ...

  7. springboot No Java compiler available for configuration options compilerClassName: [null] and compil

    今天使用eclipse创建springboot整合jsp出现一个问题,在idea中并没有遇到这个问题.最后发现是需要在eclipse中添加一个eclipse依赖,依赖如下: <dependenc ...

  8. 如何解决Your project contains C++ files but it is not using a supported native build system

    最近因为项目需要下载Android终端模拟器(Android-Terminal-Emulator)源码进行调试编译,编译过程中出现报错 Error:Execution failed for task ...

  9. javascript的异步编程解决方案收集

    缘起 没理解js异步的同学看下面的例子: for (var i = 0; i < 5; i++) { //模拟一个异步操作 setTimeout(() => { console.log(i ...

  10. 检查xml文件

    #coding=utf- import os import time def verify(filePath): print("verify--" + filePath) list ...