2631: tree

Time Limit: 30 Sec  Memory Limit: 128 MB
Submit: 5171  Solved: 1754
[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,q
接下来n-1行每行两个正整数u,v,描述这棵树
接下来q行,每行描述一个操作
 

Output

  对于每个/对应的答案输出一行
 

Sample Input

3 2
1 2
2 3
* 1 3 4
/ 1 1

Sample Output

4

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

Source

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#define maxn 500005
#define ls(x) t[x].s[0]
#define rs(x) t[x].s[1]
#define ll long long
#define mod 51061
using namespace std;
inline ll read() {
ll x=,f=;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-;
for(;isdigit(ch);ch=getchar()) x=x*+ch-'';
return x*f;
}
struct data {
ll s[],fa,c,a,v,sum,size;
data(){c=;v=,a=,sum=,size=;}
bool rev;
}t[maxn];
bool isroot(int x) {return ls(t[x].fa)!=x&&rs(t[x].fa)!=x;}
void pushup(int x) {t[x].sum=t[ls(x)].sum+t[rs(x)].sum+t[x].v;t[x].sum%=mod;t[x].size=t[ls(x)].size+t[rs(x)].size+;}
void cal(int x,int ce,int add) {
t[x].sum=t[x].sum*ce+add*t[x].size;t[x].sum%=mod;
t[x].v=t[x].v*ce+add;t[x].v%=mod;
t[x].c*=ce;t[x].c%=mod;
t[x].a=t[x].a*ce+add;t[x].a%=mod;
}
void pushdown(int x) {
if(t[x].rev) {
swap(ls(x),rs(x));
t[ls(x)].rev^=;t[rs(x)].rev^=;t[x].rev^=;
}
int ce=t[x].c,add=t[x].a;
t[x].c=;t[x].a=;
cal(ls(x),ce,add);cal(rs(x),ce,add);
}
void rotate(int x) {
int y=t[x].fa,z=t[y].fa;
bool l=ls(y)!=x,r=l^;
if(!isroot(y)) t[z].s[t[z].s[]==y]=x;
t[x].fa=z;t[y].fa=x;t[y].s[l]=t[x].s[r];
t[t[x].s[r]].fa=y;t[x].s[r]=y;
pushup(y);pushup(x);
}
void pre(int x) {
if(!isroot(x)) pre(t[x].fa);
pushdown(x);
}
void splay(int x) {
pre(x);
while(!isroot(x)) {
int y=t[x].fa,z=t[y].fa;
if(!isroot(y)){
if(ls(y)==x^ls(z)==y) rotate(x);
else rotate(y);
}
rotate(x);
}
}
void access(int x) {for(int y=;x;y=x,x=t[x].fa) {splay(x);t[x].s[]=y;pushup(x);}}
void mroot(int x) {access(x);splay(x);t[x].rev^=;}
void link(int x,int y) {mroot(x);t[x].fa=y;}
void cut(int x,int y) {mroot(x);access(y);splay(y);t[y].s[]=t[x].fa=;pushup(y);}
int n,q;
int main() {
n=read(),q=read();
t[].a=t[].c=t[].sum=t[].size=;
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);
if(ch[]=='+') {int u=read(),v=read();mroot(u);access(v);splay(v);ll tmp=read();cal(v,,tmp);}
if(ch[]=='-') {int u=read(),v=read();cut(u,v);u=read();v=read();link(u,v);}
if(ch[]=='*') {int u=read(),v=read();mroot(u);access(v);splay(v);ll tmp=read();cal(v,tmp,);}
if(ch[]=='/') {int u=read(),v=read();mroot(u);access(v);splay(v);printf("%lld\n",t[v].sum);}
}
return ;
}
/*
5 100
1 2 1 3 3 4 3 5
+ 4 5 3
/ 4 5
* 4 5 3
/ 4 5
- 3 4 4 5
/ 3 4
*/

最新文章

  1. CodeIgniter中驱动器的使用方法
  2. c++ ,类型转换
  3. 解决tomcat默认45s启动超时的问题
  4. eclipse ADT下载地址
  5. silverlight 文本框只能输入汉字
  6. CVirtualGridCtrl控件内的数据如何获取
  7. XtraForm中更换皮肤
  8. js中 ===与==
  9. CentOS 7 下yum安装xtrabackup备份工具
  10. 关于android多点触控
  11. 原生js轮播图
  12. 从入门到放弃,.net构建博客系统(一):系统构建篇
  13. WPF 模板绑定父级控件内容
  14. [JavaScript] 邮箱验证
  15. Activit工作流学习例子
  16. Nginx防hashdos模块使用帮助
  17. JAVA操作mysql
  18. 关于Unity中新版动画系统的使用
  19. AD 文档信息设置和制作模板
  20. Create Fiori List App Report with ABAP CDS view – PART 1

热门文章

  1. CodeForces Round #521 (Div.3) E. Thematic Contests
  2. Activiti工作流(三)——流程变量
  3. 【bzoj3931】[CQOI2015]网络吞吐量 最短路+最大流
  4. Educational Codeforces Round 53 Div. 2翻车记
  5. [bzoj4832][Lydsy1704月赛]抵制克苏恩
  6. 假的kd-tree小结
  7. BZOJ1009: [HNOI2008]GT考试 矩阵快速幂+kmp+dp
  8. JUnit4.11 理论机制 @Theory 完整解读
  9. 微信小程序,设置所有标签样式
  10. HttpClientUntils工具类的使用测试及注意事项(包括我改进的工具类和Controller端的注意事项【附 Json 工具类】)