嘟嘟嘟




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




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

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

对于区间加,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. 处理html内容,获取纯文本

    import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import java.util.rege ...

  2. SQL 拼接多个字段的值&一个字段多条记录的拼接

    如student表: studentID studentName studentScore 01 Alice 90 02 Bill 95 03 Cindy 100 一.拼接多个字段的值 select ...

  3. 安装svn过程

    1.SVN服务器端程序安装 --检测是否安装成功:svn --version2.创建版本库(仓库) 命令格式:svnadmin create 仓库的目录 3.启动服务器 <1>命令行方式 ...

  4. centos 中设置网卡等相关参数

    转:Centos启动和禁用网卡命令 ifup.ifdown:linux命令 实时地手动修改一些网络接口参数,可以利用ifconfig来实现,如果是要直接以配置文件,在  /etc/sysconfig/ ...

  5. 【JavaFx教程】第五部分:将数据用 XML 格式存储

    第5部分的主题 持久化数据为XML 使用JavaFX的FileChooser 使用JavaFX的菜单 在用户设置中保存最后打开的文件路径. 现在我们的地址应用程序的数据只保存在内存中.每次我们关闭应用 ...

  6. 本地chrome调试服务器node

    Node内置了V8引擎提供的 inspector 调试器,可以通过 TCP 协议从外部访问这个调试器,方便对Node程序进行调试.启动调试的标志有: Flag Meaning --inspect En ...

  7. css之background-position属性实现雪碧图

    什么是雪碧图 雪碧图就是CSS Sprite,也有人叫它CSS精灵,是一种CSS图像合并技术,就是把多张小图标合并到一张图片上,然后用css的background-position来显示需要显示的部分 ...

  8. 通过sql的DMV查看数据库使用状态

    --数据库隔离级别 读未提交 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; --查找每次执行时引发I/O最多的前10位的查询 total_logi ...

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

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

  10. SQL、HQL、JPQL、CQL的对比

    SQL:全称结构化查询语言(Structured Query Language),是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询.更新和管理关系数据库系统:同时也是数据 ...