【BZOJ】2631: tree LCT
【题意】给定n个点的树,每个点初始权值为1,m次操作:1.x到y的点加值,2.断一条边并连一条边,保证仍是树,3.x到y的点乘值,4.x到y的点权值和取模。n,m<=10^5。
【算法】Link-Cut Tree
【题解】区间加和区间乘标记的处理:【BZOJ】1798: [Ahoi2009]Seq 维护序列seq 线段树
splay上维护要注意:
1.上传时加本身。
2.改值的时候不能影响到0点。
3.所有改变点的儿子的地方都要上传,所有改变点的父亲的地方都要下传。
除了rotate,还有access的时候要上传up。
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#define int unsigned int
using namespace std;
int read(){
int s=,t=;char c;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
const int maxn=,MOD=;
int n,Q,sum[maxn],A[maxn],B[maxn],g[maxn],a[maxn],sz[maxn],t[maxn][],f[maxn],N[maxn];
int M(int x){return x>=MOD?x-MOD:x;}
void up(int x){sum[x]=M(M(sum[t[x][]]+sum[t[x][]])+a[x]);sz[x]=sz[t[x][]]+sz[t[x][]]+;}
void modify_a(int k,int x){
if(!k)return;
a[k]=M(a[k]+x);
sum[k]=M(sum[k]+sz[k]*x%MOD);
A[k]=M(A[k]+x);
}//make 0 no influence
void modify_b(int k,int x){
if(!k)return;
a[k]=a[k]*x%MOD;
sum[k]=sum[k]*x%MOD;A[k]=A[k]*x%MOD;B[k]=B[k]*x%MOD;
}
void down(int k){
if(g[k]){
swap(t[k][],t[k][]);
if(t[k][])g[t[k][]]^=;
if(t[k][])g[t[k][]]^=;
g[k]=;
}
if(B[k]!=){
modify_b(t[k][],B[k]);modify_b(t[k][],B[k]);
B[k]=;
}
if(A[k]){
modify_a(t[k][],A[k]);modify_a(t[k][],A[k]);
A[k]=;
}
}
bool isroot(int x){return !x||(t[f[x]][]!=x&&t[f[x]][]!=x);}
void rotate(int y){
int x=f[y];
int k=y==t[x][];
t[x][!k]=t[y][k];f[t[y][k]]=x;
if(!isroot(x))t[f[x]][x==t[f[x]][]]=y;f[y]=f[x];f[x]=y;
t[y][k]=x;
up(x);up(y);
}
void splay(int x){
int top=x,tot=;N[]=x;
while(!isroot(top))top=f[top],N[++tot]=top;
for(int i=tot;i>=;i--)down(N[i]);
while(!isroot(x)){
if(isroot(f[x])){rotate(x);break;}
int X=x==t[f[x]][],Y=f[x]==t[f[f[x]]][];
if(X^Y)rotate(x),rotate(x);
else rotate(f[x]),rotate(x);
}
}
void access(int x){
int y=;
while(x){
splay(x);
t[x][]=y;
up(x);///
y=x;x=f[x];
}
}
void reserve(int x){access(x);splay(x);g[x]^=;}
void link(int x,int y){reserve(x);f[x]=y;}
void find(int x,int y){reserve(x);access(y);splay(y);}
void cut(int x,int y){find(x,y);t[y][]=f[x]=;} char s[];
#undef int
int main(){
#define int unsigned int
n=read();Q=read();
for(int i=;i<=n;i++)sum[i]=a[i]=,sz[i]=,A[i]=,B[i]=;
for(int i=;i<n;i++)link(read(),read());
while(Q--){
scanf("%s",s);
int x=read(),y=read();
if(s[]=='+'){
int z=read();
find(x,y);modify_a(y,z);
}
if(s[]=='-'){
int u=read(),v=read();
cut(x,y);link(u,v);
}
if(s[]=='*'){
int z=read();
find(x,y);modify_b(y,z);
}
if(s[]=='/'){
find(x,y);printf("%d\n",sum[y]);
}
}
return ;
}
【BZOJ】2631: tree LCT的更多相关文章
- 【BZOJ】1468: Tree(POJ1741) 点分治
[题意]给定带边权树,求两点距离<=k的点对数.n<=40000. [算法]点分治 [题解]对于一个区域,选择其重心x作为根,则划分出来的每棵子树都是子区域,可以证明至多划分log n次( ...
- 【BZOJ】3282: Tree(lct)
http://www.lydsy.com/JudgeOnline/problem.php?id=3282 复习了下lct,发现两个问题.. 1:一开始我以为splay那里直接全部rot(x)就好了,然 ...
- 【BZOJ】1468: Tree(点分治)
http://www.lydsy.com/JudgeOnline/problem.php?id=1468 分治真是一门高大上的东西... 好神... 树分治最好资料是:qzc的<分治算法在树的路 ...
- 【BZOJ】2049: [Sdoi2008]Cave 洞穴勘测 LCT
[题意]给定n个点和m个操作,每次操作:1.连接2个点.2.断开2个点.3.查询2个点是否连通.m<=2*10^5. [算法]Link-Cut Tree [题解]LCT模板题,Link,Cut, ...
- 【BZOJ】4764: 弹飞大爷 LCT
[题意]给定n个数字ai,表示大爷落到i处会被弹飞到i+ai处,弹飞到>n或<1处则落地.m次操作,修改一个ai,或询问大爷落到x处经过几次落地(或-1).n,m<=10^5,|ai ...
- 【BZOJ】3091: 城市旅行 Link-Cut Tree
[题意]参考PoPoQQQ. 给定一棵树,每个点有一个点权,提供四种操作: 1.删除两点之间的连边 不存在边则无视 2.在两点之前连接一条边 两点已经联通则无视 3.在两点之间的路径上所有点的点权加上 ...
- 【BZOJ】3779 重组病毒
[算法]Link-Cut Tree+线段树(维护DFS序) [题解]整整三天……T_T 这篇题解比较资瓷:permui 这道题虽然树形态没有变化,但用lct写的原因在于把题目中的操作一进行了神转化:每 ...
- 【BZOJ】3052: [wc2013]糖果公园
http://www.lydsy.com/JudgeOnline/problem.php?id=3052 题意:n个带颜色的点(m种),q次询问,每次询问x到y的路径上sum{w[次数]*v[颜色]} ...
- 【BZOJ】3319: 黑白树
http://www.lydsy.com/JudgeOnline/problem.php?id=3319 题意:给一棵n节点的树(n<=1e6),m个操作(m<=1e6),每次操作有两种: ...
随机推荐
- 操作系统之实验二Step1-有序顺序表
实验二Step1-有序顺序表 专业:商业软件工程 班级:商软2班 姓名:甘佳萍 学号:201406114207 实验要求:初始化 输入数组元素个数. 输入n个数,排序输出. 存 ...
- IT行业所面临的问题
在阅读了“2015 IT行业大学生就业分析报告”和“2014年十大最热门行业和职业排行榜 IT行业最吃香_联展新闻”两则新闻后,我决定用一篇和老师对话的形式来表达我的感受. dym:人潮汹涌的招聘市场 ...
- KeyBoard 操作 !
键盘操作:tab/ enter/ crtl+c ,crtl+v ; import java.awt.*; import java.awt.datatransfer.StringSelection; i ...
- vbs习题
练习题: 1.输入3个数,输出其中最大的那个值. Option Explicit Dim intA,intB,intC intA=CInt(InputBox("请输入a:")) i ...
- crontab部署定时任务
1.安装cron工具:apt-getinstall cron 2.开启定时任务:crontab –e 定时任务语句格式为:执行周期+命令. 周期有5个域,分别是分,时,日(day of month), ...
- JavaScript判断密码强度
以下是代码: <html> <head> <title>JS判断密码强度</title> <script language=javascript& ...
- UVALive6434_Number Assignment
简单dp题. 这样的,意思为给你n个数,要你现在将这n个数分为m组,使得所有组内最大值与最小值的差的和最小. 其实可以这样来考虑这个问题,首先可以把所有的数字从小到大排个序,显然如果有一种取法是最优的 ...
- BZOJ 2957 楼房重建(线段树区间合并)
一个显而易见的结论是,这种数字的值是单调递增的.我们修改一个数只会对这个数后面的数造成影响.考虑线段树划分出来的若干线段. 这里有两种情况: 1.某个线段中的最大值小于等于修改的数,那么这个线段的贡献 ...
- BZOJ3712 PA2014Fiolki(kruskal重构树)
对合并过程建树.然后只需要按照时间顺序考虑每个反应就行了,时间顺序根据lca的深度确定. #include<iostream> #include<cstdio> #includ ...
- 【BZOJ1565】【NOI2009】植物大战僵尸(网络流)
[BZOJ1565][NOI2009]植物大战僵尸(网络流) 题面 BZOJ 洛谷 题解 做了这么多神仙题,终于有一道能够凭借自己智商能够想出来的题目了.... 好感动. 这就是一个比较裸的最小割模型 ...