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

  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. C编程经验总结4

    {}体里的语句不管在一行还是在多行,之间都是要有: for与for之间可以是独立的,也可以是相互嵌套的 For( ; i<5; )=for( ;i<=4;  ) 一般都是在循环里面进行判断 ...

  2. link链接外部样式表

    一个完整的link标签: <link href="[css adress]" rel="stylesheet" type="text/css&q ...

  3. MySql客户端远程连接MySql服务器

    设置MySql服务器以接听端口及以绑定IP地址 MySql服务器默认监听3306端口,确定防火墙以开放此端口. 编辑/etc/my.cnf 添加绑定IP地址.bind-address=192.168. ...

  4. BZOJ3884: 上帝与集合的正确用法(欧拉函数 扩展欧拉定理)

    Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 3860  Solved: 1751[Submit][Status][Discuss] Descripti ...

  5. Q&A - Apache、Nginx与Tomcat的区别?

    一.     定义: 1.     Apache Apache HTTP服务器是一个模块化的服务器,可以运行在几乎所有广泛使用的计算机平台上.其属于应用服务器.Apache支持支持模块多,性能稳定,A ...

  6. docker基础——关于安装、常用指令以及镜像制作初体验

    为什么使用docker docker就是一个轻量级的虚拟机,他解决的是服务迁移部署的时候环境配置问题.比如常见的web服务依赖于jdk.Tomcat.数据库等工具,迁移项目就需要在新的机器重新配置这些 ...

  7. 如何快速查看mysql数据文件存放路径?

    进入mysql终端 mysql>show variables like '%datadir%'; 出来的结果即是!

  8. VM虚拟机里的Ubuntu系统怎么设置屏幕分辨率

    说白了就是安装VMWare tools工具,步骤如下: 1)在VMWare中启动ubuntu虚拟机 2)在VMWare中:右键单击启动虚拟机,点击[安装vmware tools] 3)在ubuntu中 ...

  9. 【PHP项目】$_SEVER详解

    $_SERVER['HTTP_ACCEPT_LANGUAGE']//浏览器语言 $_SERVER['REMOTE_ADDR'] //当前用户 IP . $_SERVER['REMOTE_HOST'] ...

  10. win8电脑字体出现方格的解决方法

    一般电脑出现乱码有几种可能,最常见的可能就是电脑字体的丢失,其次就是电脑字体被病毒所损坏,因此,首先我们要做的就是下载字体并进行安装. 下载 simsun.tcc点击安装,如果电脑字体依然是这种情况( ...