【bzoj2631】tree link-cut-tree
2016-06-01 08:50:36
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2631
注意加和乘的标记下传问题。
还有就是split后,要分清x和y哪个是祖先。
pushup在access和rotate后都要进行。
这题还卡常数,开ll就会T,开unsigned int即可。
#include<bits/stdc++.h>
#define inf 1000000000
#define uint unsigned int
#define N 100005
#define mod 51061
using namespace std;
int read(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,q;
char ch[];
namespace LCT{
int ch[N][],fa[N],sz[N];bool rev[N];
uint cj[N],add[N],val[N],sum[N];
inline bool isroot(int x){
if(ch[fa[x]][]!=x&&ch[fa[x]][]!=x)return ;return ;
}
void change(int x,int c,int a){
if(!x)return;
val[x]=(val[x]*c+a)%mod;
sum[x]=(sum[x]*c+a*sz[x])%mod;
add[x]=(add[x]*c+a)%mod;
cj[x]=(cj[x]*c)%mod;
}
void pushdown(int x){
if(rev[x]){
rev[ch[x][]]^=;rev[ch[x][]]^=;rev[x]^=;
swap(ch[x][],ch[x][]);
}
if(cj[x]!=||add[x]!=){
change(ch[x][],cj[x],add[x]);
change(ch[x][],cj[x],add[x]);
}
cj[x]=;add[x]=;
}
void Pushdown(int x){
if(!isroot(x))Pushdown(fa[x]);
pushdown(x);
}
void pushup(int x){
sum[x]=(sum[ch[x][]]+sum[ch[x][]]+val[x])%mod;
sz[x]=(sz[ch[x][]]+sz[ch[x][]]+)%mod;
}
void rotate(int x){
int y=fa[x],k=ch[y][]==x;
if(!isroot(y))ch[fa[y]][ch[fa[y]][]==y]=x;
fa[x]=fa[y];
fa[ch[x][!k]]=y;
fa[y]=x;
ch[y][k]=ch[x][!k];
ch[x][!k]=y;
pushup(y);pushup(x);
}
void splay(int x){
Pushdown(x);
for(int y=fa[x];!isroot(x);y=fa[x]){
if(!isroot(y)){
if((ch[fa[y]][ch[fa[y]][]==y])!=(ch[y][]==x))rotate(x);
else rotate(y);
}rotate(x);
}
}
inline void access(int x){
int y=;
while(x){
splay(x);
ch[x][]=y;pushup(x);
x=fa[y=x];
}
}
inline void moveroot(int x){
access(x);splay(x);rev[x]^=;
}
inline void link(int x,int y){
moveroot(x);fa[x]=y;splay(x);
}
inline void cut(int x,int y){
moveroot(x);access(y);splay(y);ch[y][]=fa[x]=;
}
inline void split(int x,int y){
moveroot(y);access(x);splay(x);
}
}
int main(){
n=read();q=read();
for(int i=;i<=n;i++)LCT::val[i]=LCT::sum[i]=LCT::cj[i]=LCT::sz[i]=;
for(int i=;i<n;i++)LCT::link(read(),read());
while(q--){
scanf("%s",ch);
int u=read(),v=read();
if(ch[]=='+')LCT::split(u,v),LCT::change(u,,read());
else if(ch[]=='-'){
LCT::cut(u,v);u=read();v=read();LCT::link(u,v);
}
else if(ch[]=='*')LCT::split(u,v),LCT::change(u,read(),);
else LCT::split(u,v),printf("%d\n",LCT::sum[u]%mod);
}
return ;
}
2631: tree
Time Limit: 30 Sec Memory Limit: 128 MB
Submit: 3385 Solved: 1137
[Submit][Status][Discuss]
Description
一棵n个点的树,每个点的初始权值为1。对于这棵树有q个操作,每个操作为以下四种操作之一:
+ u v c:将u到v的路径上的点的权值都加上自然数c;
- u1 v1 u2 v2:将树中原有的边(u1,v1)删除,加入一条新边(u2,v2),保证操作完之后仍然是一棵树;
* u v c:将u到v的路径上的点的权值都乘上自然数c;
/ u v:询问u到v的路径上的点的权值和,求出答案对于51061的余数。
Input
接下来n-1行每行两个正整数u,v,描述这棵树
接下来q行,每行描述一个操作
Output
Sample Input
1 2
2 3
* 1 3 4
/ 1 1
Sample Output
HINT
数据规模和约定
10%的数据保证,1<=n,q<=2000
另外15%的数据保证,1<=n,q<=5*10^4,没有-操作,并且初始树为一条链
另外35%的数据保证,1<=n,q<=5*10^4,没有-操作
100%的数据保证,1<=n,q<=10^5,0<=c<=10^4
【bzoj2631】tree link-cut-tree的更多相关文章
- 【BZOJ 3282】Tree Link Cut Tree模板题
知道了为什么要换根(changeroot),access后为什么有时要splay,以及LCT的其他操作,算是比较全面的啦吧,,, 现在才知道这些,,,真心弱,,, #include<cstdio ...
- 【学习笔记】LCT link cut tree
大概就是供自己复习的吧 1. 细节讲解 安利两篇blog: Menci 非常好的讲解与题单 2.模板 把 $ rev $ 和 $ pushdown $ 的位置记清 #define lc son[x][ ...
- bzoj 3282: Tree (Link Cut Tree)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3282 题面: 3282: Tree Time Limit: 30 Sec Memory L ...
- P3690 【模板】Link Cut Tree (动态树)
P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...
- LG3690 【模板】Link Cut Tree (动态树)
题意 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联通的 ...
- AC日记——【模板】Link Cut Tree 洛谷 P3690
[模板]Link Cut Tree 思路: LCT模板: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 30 ...
- LG3690 【模板】Link Cut Tree 和 SDOI2008 洞穴勘测
UPD:更新了写法. [模板]Link Cut Tree 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 后接两个整数(x,y),代表询问从x到y ...
- (RE) luogu P3690 【模板】Link Cut Tree
二次联通门 : luogu P3690 [模板]Link Cut Tree 莫名RE第8个点....如果有dalao帮忙查错的话万分感激 #include <cstdio> #includ ...
- LuoguP3690 【模板】Link Cut Tree (动态树) LCT模板
P3690 [模板]Link Cut Tree (动态树) 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两 ...
- 【刷题】洛谷 P3690 【模板】Link Cut Tree (动态树)
题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor ...
随机推荐
- How many Fibs?【sudt 2321】【大数的加法及其比较】
How many Fibs? Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 Recall the definition of t ...
- maven 依赖查询
该文章源地址:http://xiejianglei163.blog.163.com/blog/static/1247276201362733217604/ 为方便个人使用,转载于此处. http:// ...
- Oracle merge
oracle merge 語法:
- js setTimeout运用
js setTimeout运用 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "ht ...
- PS 零基础训练1
背景色:Alt + Del 前景色:Ctrl + Del 快捷键: 更换工具栏里的第二项:Shift + W or Shift + C ... 缩放:Ctrl + = or Ctrl + - 工具笔 ...
- php判断当前的访问是手机还是电脑
<?php function check_wap() { if (isset($_SERVER['HTTP_VIA'])) return true; if (isset($_SERVER['HT ...
- [J2EE] 在Web如何取得相关路径
来自网络,自己整整一下: request.getRealPath("url"); // 虚拟目录映射为实际目录,不建议使用,使用ServletContext.getRealPath ...
- 注解:【有连接表的】Hibernate单向N->1关联
Person与Address关联:单向N->1,[有连接表的] Person.java package org.crazyit.app.domain; import javax.persiste ...
- VIM学习笔记
参考: http://linux.chinaunix.net/techdoc/beginner/2009/12/20/1150108.shtml VIM命令大全 光标控制命令 命令 ...
- Unity2D 之 Sprite点击事件
以下方法纯属我YY,切勿当真!!! 给 Sprite添加点击事件步骤: 1. 创建一个 Sprite 2. 给Sprite添加一个 Box Collider 2D 3. 将如果脚本放到Sprite上: ...