题目大意:给一棵树,有四种操作:

  1. $+\;u\;v\;c:$将路径$u->v$区间加$c$
  2. $-\;u_1\;v_1\;u_2\;v_2:$将边$u_1-v_1$切断,改成边$u_2-v_2$,保证数据合法
  3. $*\;u\;v\;c:$将路径$u->v$区间乘$c$
  4. $/\;u\;v:$询问路径$u->v$区间和

题解:$LCT$乱搞

卡点:

C++ Code:

#include <cstdio>
#define maxn 100010
#define lc(rt) son[rt][0]
#define rc(rt) son[rt][1]
const long long mod = 51061;
int n, q;
long long V[maxn], s[maxn], tg[maxn], M[maxn], A[maxn];
int son[maxn][2], fa[maxn], sz[maxn];
inline void swap(int &a, int &b) {a ^= b ^= a ^= b;}
inline void swap(int x) {
swap(lc(x), rc(x));
tg[lc(x)] ^= 1, tg[rc(x)] ^= 1, tg[x] = 0;
}
inline void setmul(int x) {
long long &tmp = M[x];
M[lc(x)] = M[lc(x)] * tmp % mod, M[rc(x)] = M[rc(x)] * tmp % mod;
A[lc(x)] = A[lc(x)] * tmp % mod, A[rc(x)] = A[rc(x)] * tmp % mod;
V[lc(x)] = V[lc(x)] * tmp % mod, V[rc(x)] = V[rc(x)] * tmp % mod;
s[lc(x)] = s[lc(x)] * tmp % mod, s[rc(x)] = s[rc(x)] * tmp % mod;
tmp = 1;
}
inline void setadd(int x) {
long long &tmp = A[x];
A[lc(x)] = (A[lc(x)] + tmp) % mod, A[rc(x)] = (A[rc(x)] + tmp) % mod;
V[lc(x)] = (V[lc(x)] + tmp) % mod, V[rc(x)] = (V[rc(x)] + tmp) % mod;
s[lc(x)] = (s[lc(x)] + sz[lc(x)] * tmp) % mod, s[rc(x)] = (s[rc(x)] + sz[rc(x)] * tmp) % mod;
tmp = 0;
}
inline void pushdown(int x) {
if (tg[x]) swap(x);
if (M[x] != 1) setmul(x);
if (A[x]) setadd(x);
}
inline void update(int x) {
s[x] = (s[lc(x)] + s[rc(x)] + V[x]) % mod;
sz[x] = sz[lc(x)] + sz[rc(x)] + 1;
}
inline int get(int x) {return rc(fa[x]) == x;}
inline bool isrt(int x) {return lc(fa[x]) != x && rc(fa[x]) != x;}
inline void rotate(int x) {
int y = fa[x], z = fa[y], b = get(x);
if (!isrt(y)) son[z][get(y)] = x;
fa[son[y][b] = son[x][!b]] = y; son[x][!b] = y;
fa[y] = x, fa[x] = z;
update(y), update(x);
}
int S[maxn], top;
inline void splay(int x) {
S[top = 1] = x;
for (int y = x; !isrt(y); S[++top] = y = fa[y]);
for (; top; top--) pushdown(S[top]);
for (; !isrt(x); rotate(x)) if (!isrt(fa[x]))
get(x) ^ get(fa[x]) ? rotate(x) : rotate(fa[x]);
update(x);
}
inline void access(int x) {for (int t = 0; x; rc(x) = t, t = x, x = fa[x]) splay(x);}
inline void mkrt(int x) {access(x), splay(x), tg[x] ^= 1;}
inline void link(int x, int y) {mkrt(x), fa[x] = y;}
inline void split(int x, int y) {mkrt(x), access(y), splay(y);}
inline void cut(int x, int y) {split(x, y), lc(y) = fa[x] = 0;}
inline void add(int x, int y, long long num) {
split(x, y);
A[y] = (A[y] + num) % mod;
V[y] = (V[y] + num) % mod;
s[y] = (s[y] + sz[y] * num) % mod;
}
inline void mul(int x, int y, long long num) {
split(x, y);
A[y] = A[y] * num % mod;
V[y] = V[y] * num % mod;
M[y] = M[y] * num % mod;
s[y] = s[y] * num % mod;
}
inline long long query(int x, int y) {
split(x, y);
pushdown(y);
return s[y];
} int main() {
scanf("%d%d", &n, &q);
for (int i = 1; i <= n; i++) V[i] = 1, M[i] = 1, s[i] = 1;
for (int i = 1; i < n; i++) {
int a, b;
scanf("%d%d", &a, &b);
link(a, b);
}
while (q --> 0) {
int x, y;
long long z;
char op[10];
scanf("%s%d%d", op, &x, &y);
switch (*op) {
case '+': scanf("%lld", &z), add(x, y, z); break;
case '-': cut(x, y), scanf("%d%d", &x, &y), link(x, y); break;
case '*': scanf("%lld", &z), mul(x, y, z); break;
case '/': printf("%lld\n", query(x, y));
}
}
return 0;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

  7. 洛谷 P1501 [国家集训队]Tree II Link-Cut-Tree

    Code: #include <cstdio> #include <algorithm> #include <cstring> #include <strin ...

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

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

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

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

随机推荐

  1. java基础必备单词讲解 day three

    if 如果 else 否则 switch 切换判断 case 实例 break 退出 return 返回 default 默认 variable array 数组 null 空的 无效的 pointe ...

  2. H5新增的Web Storage本地存储

    html5中的Web Storage包括了两种存储方式:sessionStorage和localStorage. sessionStorage用于本地存储一个会话(session)中的数据,这些数据只 ...

  3. JS里访问纯数字ID对象时出现问题

    <p id="1">Hello</p> 例如上面的例子,id为纯数字会出错.此时用js去获取该对象会报错,查找不到该对象. 原因:必须是字母开头,或是下划线 ...

  4. LeetCode297. Serialize and Deserialize Binary Tree

    题目 序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据. 请设计一个算法来实 ...

  5. js jquery 权限单选 bug修改以及正确代码 购物车数量加减

    效果图废话不多直接上代码 用的avalon渲染,其实都是一样的 <div class="shop-arithmetic"> <a href="javas ...

  6. 给网站添加icon图标

    只需制成ico结尾的图片即可

  7. 基于Select模型通信程序的编写,编译和执行

    任务目标 编写Win32程序模拟实现基于Select模型的两台计算机之间的通信,要求编程实现服务器端与客户端之间双向数据传递.客户端向服务器端发送"计算从1到100的奇数和",服务 ...

  8. scrapy--json(喜马拉雅Fm)

    已经开始听喜马拉雅Fm电台有2个月,听里面的故事,感觉能听到自己,特别是蕊希电台,始于声音,陷于故事,忠于总结.感谢喜马拉雅Fm陪我度过了这2个月,应该是太爱了,然后就开始对Fm下手了.QAQ 该博客 ...

  9. 深入理解yii2之RBAC(模块化系统)

    一.前言 上一篇文章我们已经大致谈过RBAC到底是什么和yii2底层RBAC接口的分析. 下面我深入理解一下RBAC权限分配,深入理解下yii2底层RBAC扩展,以及它是如何针对模块化系统的开发的? ...

  10. Numpy安装报错:试过N种安装方法终于

    Import numpy时,会报下面的错误 /home/spyros/.local/lib/python2.7/site-packages/numpy/core/multiarray.so: unde ...