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 思路: 线段树首先就是递归建 ...
随机推荐
- MySQL防止重复插入记录SQL
INSERT INTO sysuser(') DUAL:表示虚拟表 sysuser:表名称
- [转]在WIN7下安装运行mongodb
本文转自:http://www.cnblogs.com/snake-hand/p/3172376.html 1).下载MongoDB http://downloads.mongodb.org/win3 ...
- Tomcat+Jenkins+SonarQube+SVN+Maven 集成自动化环境搭建(Windows10环境下)
说在前面的话: 从接到任务到完成共用了7天的时间.正常人用不到这个时间. 此时的功能表现是: 登录本地JenKins对项目进行构建,能够自动从SVN读取最新代码并按照Maven项目构建,构建完成能够自 ...
- canvas防画图工具
<style> body { background: black; text-align: center; } #cans { background: white; } < ...
- java实现汉诺塔算法
package com.ywx.count; import java.util.Scanner; /** * @author Vashon * date:20150410 * * 题目:汉诺塔算法(本 ...
- ios---setContentOffset
UIView * farmeView=[[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self. ...
- asp.net mvc 5 微信接入VB版 - 接入认证
微信接入官方文档是php的,网上被抄好几遍的代码是c#的,就是没vb的.今天我把这个坑填了,做vb版的接入认证. 首先是照着开发文档把微信接入的模型写好.在Models文件夹新建一个Model Pub ...
- java环境变量配置-简易菜鸟版
NO1:Path配置: 用户Path:%JAVA_HOME%\bin 系统Path:%java_home%\bin;%java_home%\jre\bin NO2:CLASSPATH配置: .;%ja ...
- PHP一句话后门过狗姿势万千之理论篇
写在前面: 过狗相关的资料网上也是有很多,所以在我接下来的文章中,可能观点或者举例可能会与网上部分雷同,或者表述不够全面. 但是我只能说,我所传达给大家的信息,是我目前所掌握或者了解的,不能保证所有人 ...
- zabbix设置多个收件人
1.建群组 2.添加群组权限 3.添加用户,归属到上面新建的组 4.动作里发送消息给新建的组 5.这样设置后,管理员账号不用设置收件媒介