洛谷P1501 Tree II
LCT
还是LCT的板子,下放标记和那道线段树2一样,先放乘。。之前用char忘记getchar,调了好久。。。
注意开long long!!
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define full(a, b) memset(a, b, sizeof a)
using namespace std;
typedef long long ll;
inline int lowbit(int x){ return x & (-x); }
inline int read(){
int X = 0, w = 0; char ch = 0;
while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
return w ? -X : X;
}
inline int gcd(int a, int b){ return a % b ? gcd(b, a % b) : b; }
inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
template<typename T>
inline T max(T x, T y, T z){ return max(max(x, y), z); }
template<typename T>
inline T min(T x, T y, T z){ return min(min(x, y), z); }
template<typename A, typename B, typename C>
inline A fpow(A x, B p, C lyd){
A ans = 1;
for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
return ans;
}
const ll N = 200005;
ll n, q, tot, p, ch[N][2], size[N], rev[N], val[N], fa[N], sum[N], mul[N], add[N], st[N];
void newNode(ll v){
val[++tot] = v; size[tot] = mul[tot] = 1, sum[tot] = v;
ch[tot][0] = ch[tot][1] = fa[tot] = rev[tot] = add[tot] = 0;
}
bool isRoot(ll x){
return (ch[fa[x]][0] != x && ch[fa[x]][1] != x);
}
void pushMul(ll x, ll c){
mul[x] *= c, add[x] *= c, sum[x] *= c, val[x] *= c;
mul[x] %= p, add[x] %= p, sum[x] %= p, val[x] %= p;
}
void pushAdd(ll x, ll c){
add[x] += c, sum[x] += size[x] * c, val[x] += c;
add[x] %= p, sum[x] %= p, val[x] %= p;
}
void pushRev(ll x){
rev[x] ^= 1, swap(ch[x][0], ch[x][1]);
}
void push_up(ll x){
size[x] = size[ch[x][0]] + size[ch[x][1]] + 1;
sum[x] = (sum[ch[x][0]] + sum[ch[x][1]] + val[x]) % p;
}
void push_down(ll x){
ll l = ch[x][0], r = ch[x][1];
if(mul[x] != 1){
if(l) pushMul(l, mul[x]);
if(r) pushMul(r, mul[x]);
}
if(add[x]){
if(l) pushAdd(l, add[x]);
if(r) pushAdd(r, add[x]);
}
if(rev[x]){
if(l) pushRev(l);
if(r) pushRev(r);
}
mul[x] = 1, add[x] = 0, rev[x] = 0;
}
void rotate(ll x){
ll y = fa[x], z = fa[y], p = (ch[y][1] == x) ^ 1;
push_down(y), push_down(x);
ch[y][p^1] = ch[x][p], fa[ch[x][p]] = y;
if(!isRoot(y)) ch[z][ch[z][1] == y] = x;
fa[x] = z, fa[y] = x, ch[x][p] = y;
push_up(y), push_up(x);
}
void splay(ll x){
ll pos = 0; st[++pos] = x;
for(ll i = x; !isRoot(i); i = fa[i]) st[++pos] = fa[i];
while(pos) push_down(st[pos--]);
while(!isRoot(x)){
ll y = fa[x], z = fa[y];
if(!isRoot(y)){
if((ch[y][0] == x) ^ (ch[z][0] == y)) rotate(x);
else rotate(y);
}
rotate(x);
}
push_up(x);
}
void access(ll x){
for(ll pre = 0; x; pre = x, x = fa[x])
splay(x), ch[x][1] = pre, push_up(x);
}
void makeRoot(ll x){
access(x), splay(x), pushRev(x);
}
void split(ll x, ll y){
makeRoot(x), access(y), splay(y);
}
ll findRoot(ll x){
access(x), splay(x);
while(ch[x][0]) x = ch[x][0];
splay(x);
return x;
}
void link(ll x, ll y){
makeRoot(x);
if(findRoot(y) != x) fa[x] = y;
push_up(y);
}
void cut(ll x, ll y){
makeRoot(x);
if(findRoot(y) == x && fa[y] == x && !ch[y][0]){
fa[y] = ch[x][1] = 0, push_up(x);
}
}
int main(){
p = 51061;
scanf("%lld%lld", &n, &q);
for(int i = 1; i <= n; i ++) newNode(1);
for(int i = 1; i <= n - 1; i ++){
ll u, v; scanf("%lld%lld", &u, &v);
link(u, v);
}
while(q --){
char ch[10]; scanf("%s", &ch);
if(ch[0] == '+'){
ll u, v; scanf("%lld%lld", &u, &v);
ll c; scanf("%lld", &c);
split(u, v), pushAdd(v, c);
}
else if(ch[0] == '-'){
ll u, v; scanf("%lld%lld", &u, &v);
ll x, y; scanf("%lld%lld", &x, &y);
cut(u, v), link(x, y);
}
else if(ch[0] == '*'){
ll u, v; scanf("%lld%lld", &u, &v);
ll c; scanf("%lld", &c);
split(u, v), pushMul(v, c);
}
else if(ch[0] == '/'){
ll u, v; scanf("%lld%lld", &u, &v);
split(u, v);
printf("%lld\n", sum[v] % p);
}
}
return 0;
}
洛谷P1501 Tree II的更多相关文章
- 洛谷1501 Tree II(LCT,路径修改,路经询问)
这个题是一个经典的维护路径信息的题,对于路径上的修改,我们只需要把对应的链\(split\)上来,然后修改最上面的点就好,注意pushdown的时候的顺序是先乘后加 然后下传乘法标记的时候,记得把对应 ...
- 洛谷 P1501 [国家集训队]Tree II 解题报告
P1501 [国家集训队]Tree II 题目描述 一棵\(n\)个点的树,每个点的初始权值为\(1\).对于这棵树有\(q\)个操作,每个操作为以下四种操作之一: + u v c:将\(u\)到\( ...
- 洛谷P1501 [国家集训队]Tree II(LCT,Splay)
洛谷题目传送门 关于LCT的其它问题可以参考一下我的LCT总结 一道LCT很好的练习放懒标记技巧的题目. 一开始看到又做加法又做乘法的时候我是有点mengbi的. 然后我想起了模板线段树2...... ...
- 点分治模板(洛谷P4178 Tree)(树分治,树的重心,容斥原理)
推荐YCB的总结 推荐你谷ysn等巨佬的详细题解 大致流程-- dfs求出当前树的重心 对当前树内经过重心的路径统计答案(一条路径由两条由重心到其它点的子路径合并而成) 容斥减去不合法情况(两条子路径 ...
- Poj1741/洛谷P4718 Tree(点分治)
题面 有多组数据:Poj 无多组数据:洛谷 题解 点分治板子题,\(calc\)的时候搞一个\(two\ pointers\)扫一下统计答案就行了. #include <cmath> #i ...
- 【洛谷 P1501】 [国家集训队]Tree II(LCT)
题目链接 Tree Ⅱ\(=\)[模板]LCT+[模板]线段树2.. 分别维护3个标记,乘的时候要把加法标记也乘上. 还有就是模数的平方刚好爆\(int\),所以开昂赛德\(int\)就可以了. 我把 ...
- 【刷题】洛谷 P1501 [国家集训队]Tree II
题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...
- 洛谷P1501 [国家集训队]Tree II(LCT)
题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...
- 洛谷P1501 [国家集训队]Tree II(打标记lct)
题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...
随机推荐
- 微信小程序开发平台新功能「云开发」快速上手体验
微信小程序开发平台刚刚开放了一个全新的功能:云开发. 简单地说就是将开发人员搭建微信小程序后端的成本再次降低,此文刚好在此产品公测时,来快速上手看看都有哪些方便开发者的功能更新. 微信小程序一直保持一 ...
- Contest1692 - 2019寒假集训第三十一场 UPC 11075 Problem D 小P的国际象棋
非常简单的单点修改+区间加+区间查询.我用的是最近刚学的区间修改版本树状数组. 直接维护即可,注意修改后的单点值已经不是a[i],或者b[i],要通过区间查询求单点.不然是错的. 区间修改版本树状数 ...
- AtCoder Beginner Contest 053
D - Card Eater Time limit : 2sec / Memory limit : 256MB Score : 400 points Problem Statement Snuke h ...
- python学习之第八篇——字典嵌套之字典中嵌套字典
cities = { 'shanghai':{'country':'china','population':10000,'fact':'good'}, 'lendon':{'country':'eng ...
- 安装配置JDK和Eclipse的步骤
导读 作为Java程序员,需要在Linux系统上安装Eclipse,很多人不知要如何安装,在安装Eclipse前,还需安装JDK,Linux下如何安装JDK和Eclipse呢?下面跟朋友们介绍下Lin ...
- 使用publisher模式控制频繁的UI输出,避免Winform界面假死
http://www.cnblogs.com/Charltsing/p/publisher.html 最近测试task并发任务的效率与线程池的区别,发现了另外一个问题.task建立任务的速度很快,输出 ...
- java.lang.LinkageError: JAXB 2.0 API is being loaded from the bootstrap classloader
我的解决办法: 1.如果是application工程,则在程序中打印出 system.out.println(System.getProperty("java.endo ...
- 软件工程(FZU2015) 赛季得分榜,第10回合(alpha冲刺)
SE_FZU目录:1 2 3 4 5 6 7 8 9 10 11 12 13 积分规则 积分制: 作业为10分制,练习为3分制:alpha30分: 团队项目分=团队得分+个人贡献分 个人贡献分: 个人 ...
- 【转】shell之for、while、until循环
一.简介 Shell编程中循环命令用于特定条件下决定某些语句重复执行的控制方式,有三种常用的循环语句:for.while和until.while循环和for循环属于“当型循环”,而unti ...
- [转帖]Nginx rewrite模块深入浅出详解
Nginx rewrite模块深入浅出详解 https://www.cnblogs.com/beyang/p/7832460.html rewrite模块(ngx_http_rewrite_modul ...