bzoj2631 tree LCT 区间修改,求和
tree
Time Limit: 30 Sec Memory Limit: 128 MB
Submit: 4962 Solved: 1697
[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
题解:
基本操作,可以作为模板题
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstdio> #define N 100007
#define ll unsigned int
using namespace std;
const int mod=;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch>''||ch<''){if (ch=='-') f=-;ch=getchar();}
while(ch<=''&&ch>=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} int n,q;
ll sum[N],num[N],add[N],mul[N],rev[N],siz[N];
int c[N][],fa[N],st[N]; void change(int p,ll mu,ll ad)
{
if (!p) return;
mul[p]=mul[p]*mu%mod;
add[p]=(add[p]*mu+ad)%mod;
num[p]=(num[p]*mu+ad)%mod;
sum[p]=(sum[p]*mu+ad*siz[p])%mod;
}
void update(int p)
{
int l=c[p][],r=c[p][];
siz[p]=(siz[l]+siz[r]+)%mod;
sum[p]=(sum[l]+sum[r]+num[p])%mod;
}
void pushdown(int p)
{
int l=c[p][],r=c[p][];
if (rev[p])
{
rev[p]^=,rev[l]^=,rev[r]^=;
swap(c[p][],c[p][]);
}
if (add[p]!=||mul[p]!=)
{
change(l,mul[p],add[p]);
change(r,mul[p],add[p]);
}
add[p]=,mul[p]=;
}
inline bool isroot(int x)
{
return c[fa[x]][]!=x&&c[fa[x]][]!=x;
}
void rotate(int x)
{
int y=fa[x],z=fa[y],l,r;
if (c[y][]==x) l=;else l=;r=l^;
if (!isroot(y))
{
if (c[z][]==y) c[z][]=x;
else c[z][]=x;
}
fa[x]=z,fa[y]=x,fa[c[x][r]]=y;
c[y][l]=c[x][r],c[x][r]=y;
update(y),update(x);
}
void splay(int x)
{
int top=;st[++top]=x;
for (int i=x;!isroot(i);i=fa[i])
st[++top]=fa[i];
for (int i=top;i>=;i--)
pushdown(st[i]);
while(!isroot(x))
{
int y=fa[x],z=fa[y];
if (!isroot(y))
{
if (c[y][]==x^c[z][]==y) rotate(x);
else rotate(y);
}
rotate(x);
}
}
void access(int x)
{
int t=;
while(x)
{
splay(x);
c[x][]=t;
update(x);
t=x,x=fa[x];
}
}
void makeroot(int x)
{
access(x);
splay(x);
rev[x]^=;
}
void link(int x,int y)
{
makeroot(x);
fa[x]=y;
splay(x);
}
void cut(int x,int y)
{
makeroot(x);
access(y);
splay(y);
fa[x]=c[y][]=;
}
int main()
{
// freopen("fzy.in","r",stdin);
// freopen("fzy.out","w",stdout); n=read(),q=read();
for (int i=;i<=n;i++)num[i]=sum[i]=mul[i]=siz[i]=;
for (int i=;i<n;i++)
{
int u=read(),v=read();
link(u,v);
}
for (int i=;i<=q;i++)
{
char ch[];
scanf("%s",ch);
switch(ch[])
{
case'+':
{
int u=read(),v=read();ll c=read();
makeroot(u),access(v),splay(v);
change(v,,c);break;
}
case'-':
{
int u1=read(),v1=read(),u2=read(),v2=read();
cut(u1,v1),link(u2,v2);break;
}
case'*':
{
int u=read(),v=read();ll c=read();
makeroot(u),access(v),splay(v);
change(v,c,);break;
}
case'/':
{
int u=read(),v=read();
makeroot(u);
access(v);
splay(v);
printf("%d\n",sum[v]);
break;
}
}
}
}
bzoj2631 tree LCT 区间修改,求和的更多相关文章
- poj 3468:A Simple Problem with Integers(线段树,区间修改求和)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 58269 ...
- HDU 5002 Tree LCT 区间更新
Tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.action?c ...
- HDU1698Just a Hook(线段树 + 区间修改 + 求和)
题目链接 分析:1-N区间内初始都是1,然后q个询问,每个询问修改区间[a,b]的值为2或3或者1,统计最后整个区间的和 本来想刷刷手速,结果还是写了一个小时,第一个超时,因为输出的时候去每个区间查找 ...
- bzoj2631: tree lct
要打mul和add的lct 50000+的mod用unsigned int好了TAT (坑爹没打pc('\n');(静态)调了好久,样例竟然只输出一个,orz,也不提示PE T_T) #include ...
- [bzoj2631]tree——lct
Brief Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: u v c:将u到v的路径上的点的权值都加上自然数c: u1 v1 u2 ...
- bzoj 3779 重组病毒 —— LCT+树状数组(区间修改+区间查询)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3779 RELEASE操作可以对应LCT的 access,RECENTER则是 makeroo ...
- 【bzoj3779】重组病毒 LCT+树上倍增+DFS序+树状数组区间修改区间查询
题目描述 给出一棵n个节点的树,每一个节点开始有一个互不相同的颜色,初始根节点为1. 定义一次感染为:将指定的一个节点到根的链上的所有节点染成一种新的颜色,代价为这条链上不同颜色的数目. 现有m次操作 ...
- 线段树:Segment Tree(单点修改/区间修改模板) C++
线段树是非常有效的数据结构,可以快速的维护单点修改,区域修改,查询最大值,最小值等功能. 同时,它也很重要.如果有一天比赛,你卡在了一道线段树模板题目上,这就真的尴尬了.不过,随着时代的进步,题目也越 ...
- POJ - 3468 线段树单点查询,单点修改区间查询,区间修改模板(求和)
题意: 给定一个数字n,表示这段区间的总长度.然后输入n个数,然后输入q,然后输入a,b,表示查询a,b,区间和,或者输入c 再输入三个数字a,b,c,更改a,b区间为c 思路: 线段树首先就是递归建 ...
随机推荐
- C#方法拓展
作用: “扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型.” 要求: 1.拓展方法必须是在一个非嵌套.非泛型的静态类中定义.2.他至少有一个参数.3. ...
- 使用 Azure ARM 部署Word Press 遇到 Extension节点 扩展的问题
在使用Azure ARM模式部署wordpress,将php网站压缩成zip的形式在DefaultTemplate模板中已扩展的形式实现安装 遇到的问题总结: 1.开始在sites节点中,resour ...
- Linux安装技巧--安装Uuntu与windows8/10共存
1.准备安装双系统所需工具. 系统: Linux有众多的衍生版本,选择一个自己喜欢的版本下载,建议新手上ubuntu吧,中文教程较多,出了问题容易解决,等到熟悉了再用其他的也行,新手的话ubuntu也 ...
- Docker - Image创建
自己创建Image会有一些好处,可以选择最新的版本,而且从国内的镜像创建时更新软件也会从该镜像获取,速度更快. (1)安装debootstrap zhouh1@uhome:/media/zhouh1/ ...
- Win10 系统安装Sql Server2008 R2 数据库遇到的问题及解决办法总结!
1.开始安装时,提示要先安装 “.NET Framework 3.5(包括.NET 2.0和3.0)”,之前已经下载好.NET Framework 3.5 sp1,安装时还是提示要先安装 “.NET ...
- vue2.0组件生命周期探讨
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Window.Event.KeyCode的含义
Window.Event.KeyCode=13的含义(转载) 2011-04-16 09:41:18| 分类: html | 标签:keycode event realkey var do ...
- TCP和流
http://www.cnblogs.com/lwzz/archive/2011/07/03/2096963.html TCP是一种流协议(stream protocol).这就意味着数据是以字节流的 ...
- hdu5739Fantasia(多校第二场1006) 割点+逆元
Fantasia Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Proble ...
- execl, execlp, execle, execv, execvp - 执行某个文件
总览 (SYNOPSIS) #include <unistd.h> extern char **environ; int execl( const char *path, const ch ...