【问题描述】

一棵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的余数。

【输入格式】

第一行两个整数n,q
接下来n-1行每行两个正整数u,v,描述这棵树
接下来q行,每行描述一个操作

【输出格式】

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

【样例输入】

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

【样例输出】

4

【数据规模和约定】

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

  犯了几个错误:

    1.mul标记下传时没有让mul*k。

    2.数组开小了。

    3.递归栈慢!!!

    3.

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int mod=;
const int maxn=; int fir[maxn],nxt[maxn*],to[maxn*],cnt; void addedge(int a,int b){
nxt[++cnt]=fir[a];
fir[a]=cnt;
to[cnt]=b;
} int fa[maxn],rt[maxn];
int ch[maxn][],key[maxn],sz[maxn];
int sum[maxn],flip[maxn],add[maxn],mul[maxn]; void DFS(int x){
rt[x]=sz[x]=key[x]=sum[x]=mul[x]=;
for(int i=fir[x];i;i=nxt[i])
if(to[i]!=&&!fa[to[i]]){
fa[to[i]]=x;
DFS(to[i]);
}
} void Add(int x,int d){
if(!x)return;
key[x]=(key[x]+d)%mod;
add[x]=(add[x]+d)%mod;
sum[x]=(sum[x]+sz[x]*d%mod)%mod;
} void Mul(int x,int k){
key[x]=(key[x]*k)%mod;
sum[x]=(sum[x]*k)%mod;
add[x]=(add[x]*k)%mod;
} void Flip(int x){
swap(ch[x][],ch[x][]);
flip[x]^=;
} void Push_down(int x){
if(flip[x]){
Flip(ch[x][]);
Flip(ch[x][]);
flip[x]=;
}
if(mul[x]!=){
Mul(ch[x][],mul[x]);
Mul(ch[x][],mul[x]);
mul[x]=;
}
if(add[x]){
Add(ch[x][],add[x]);
Add(ch[x][],add[x]);
add[x]=;
}
} void Push_up(int x){
sz[x]=sz[ch[x][]]+sz[ch[x][]]+;
sum[x]=(sum[ch[x][]]+sum[ch[x][]]+key[x])%mod;
} void Rotate(int x){
int y=fa[x],g=fa[y],c=ch[y][]==x;
ch[y][c]=ch[x][c^];ch[x][c^]=y;
fa[ch[y][c]]=y;fa[y]=x;fa[x]=g;
if(rt[y])rt[x]=,rt[y]=;
else ch[g][ch[g][]==y]=x;
Push_up(y);
} void P(int x){
if(!rt[x])P(fa[x]);
Push_down(x);
} void Splay(int x){
P(x);
for(int y=fa[x];!rt[x];Rotate(x),y=fa[x])
if(!rt[y])Rotate((ch[fa[y]][]==y)==(ch[y][]==x)?y:x);
Push_up(x);
} void Access(int x){
int y=;
while(x){
Splay(x);
rt[ch[x][]]=;
rt[ch[x][]=y]=;
Push_up(x);
x=fa[y=x];
}
} void Make_RT(int x){
Access(x);
Splay(x);
Flip(x);
} void Link(int x,int y){
Make_RT(x);
fa[x]=y;
} void Cut(int x,int y){
Make_RT(x);
Splay(y);
fa[ch[y][]]=fa[y];fa[y]=;
rt[ch[y][]]=;ch[y][]=;
Push_up(y);
} void Lca(int &x,int &y){
Access(y);y=;
while(true){
Splay(x);
if(!fa[x])break;
rt[ch[x][]]=;
rt[ch[x][]=y]=;
Push_up(x);
x=fa[y=x];
}
} void ADD(int x,int y,int d){
Lca(x,y);
Add(y,d);Add(ch[x][],d);
key[x]=(key[x]+d)%mod;
Push_up(x);
} void MUL(int x,int y,int k){
Lca(x,y);
Mul(y,k);Mul(ch[x][],k);
key[x]=(key[x]*k)%mod;
Push_up(x);
} int Query(int x,int y){
Lca(x,y);
int ret=(key[x]+sum[y]+sum[ch[x][]])%mod;
return ret;
} int n,Q;
char op[];
int main(){
#ifndef ONLINE_JUDGE
freopen("nt2012_wym_tree.in","r",stdin);
freopen("nt2012_wym_tree.out","w",stdout);
#endif
scanf("%d%d",&n,&Q);
for(int i=,a,b;i<n;i++){
scanf("%d%d",&a,&b);
addedge(a,b);
addedge(b,a);
} DFS(); int x,y,c,u,v;
while(Q--){
scanf("%s",op);
if(op[]=='-'){
scanf("%d%d",&u,&v);Cut(u,v);
scanf("%d%d",&u,&v);Link(u,v);
}
else if(op[]=='/'){
scanf("%d%d",&x,&y);
printf("%d\n",Query(x,y));
}
else{
scanf("%d%d%d",&x,&y,&c);
if(op[]=='+')
ADD(x,y,c);
else
MUL(x,y,c);
}
}
return ;
}

爆int!!!!!

数据结构(动态树):[国家集训队2012]tree(伍一鸣)的更多相关文章

  1. [COGS 1799][国家集训队2012]tree(伍一鸣)

    Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2 ...

  2. cogs1799 [国家集训队2012]tree(伍一鸣)

    LCT裸题 注意打标记之间的影响就是了 这个膜数不会爆unsigned int #include<cstdio> #include<cstdlib> #include<a ...

  3. [国家集训队2012]tree(陈立杰)

    [国家集训队2012]tree(陈立杰) 题目 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树.题目保证有解. INPUT 第一行V,E,need分别表示 ...

  4. [国家集训队2012]tree(陈立杰) 题解(二分+最小生成树)

    tree 时间限制: 3 Sec  内存限制: 512 MB 题目描述 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解. 输入 第一行V, ...

  5. [国家集训队2012]middle

    http://cogs.pro:8080/cogs/problem/problem.php?pid=1763 二分答案x 把区间内>=x的数设为1,<x的数设为-1 左端点在[a,b]之间 ...

  6. [国家集训队2012]JZPFAR

    [国家集训队2012]JZPFAR 题目 平面上有n个点.现在有m次询问,每次给定一个点(px, py)和一个整数k,输出n个点中离(px, py)的距离第k大的点的标号.如果有两个(或多个)点距离( ...

  7. luogu P2619 [国家集训队2]Tree I

    题目链接 luogu P2619 [国家集训队2]Tree I 题解 普通思路就不说了二分增量,生成树check 说一下坑点 二分时,若黑白边权有相同,因为权值相同优先选白边,若在最有增量时出现黑白等 ...

  8. P2619 [国家集训队2]Tree I(最小生成树+二分)

    P2619 [国家集训队2]Tree I 每次二分一个$x$,每条白边加上$x$,跑最小生成树 统计一下满足条件的最小值就好了. to me:注意二分不要写挂 #include<iostream ...

  9. Luogu P2619 [国家集训队2]Tree I(WQS二分+最小生成树)

    P2619 [国家集训队2]Tree I 题意 题目描述 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有\(need\)条白色边的生成树. 题目保证有解. 输入输出格式 输入格式 ...

随机推荐

  1. IDLHDF5读取与转换

    需求决定了动力,此时近凌晨一点,忙里偷闲,终于忙完了今天的“这点儿”事儿.参考帮助文档,从hdf的读写,捉摸hdf5的读写,总算弄明白了.稍作总结,以备候查. hdf5作为hdf数据的补充与升级,目前 ...

  2. MVVM之View和ViewModel的关联

    概要: 将所有的VM在加载到Application的Static Resource中,然后在View中用标签指定. 实现: 1)采用特性指定要添加到StaticResource中的对象 public  ...

  3. ASP.NET 动态属性筛选和分页绑定

    分页控件为:AspNetPager.dll 我们先建立一个产品属性名称表 CREATE TABLE ProductAttr ( ,) NOT NULL primary key, [ParentID] ...

  4. VMware Workstation 11序列号一枚

    VMware Workstation 11序列号: 1F04Z-6D111-7Z029-AV0Q4-3AEH8

  5. ios第三方工具

    1. DXPopover  带尖叫的提示框 2. MMDrawerController 最好的抽屉效果 3.MMProgressHUD  提示框 4.Reachability :网络链接检测 UIBu ...

  6. IOS 中得runloop 详细解释

    1.Runloop基础知识- 1.1 字面意思 a 运行循环 b 跑圈 - 1.2 基本作用(作用重大) a 保持程序的持续运行(ios程序为什么能一直活着不会死) b 处理app中的各种事件(比如触 ...

  7. ios 动画效果CATransition笔记

    初学ios开发,很多概念还不清楚,所以只有边学边做例子.又怕学了后面忘了前面,因此用自己的博客来纪录自己的学习历程,也是对自己学习不要懈怠做个监督. 刚学ios做动画效果.因为ios封装得很好,实现i ...

  8. 【HDU4348】【主席树】To the moon

    Problem Description BackgroundTo The Moon is a independent game released in November 2011, it is a r ...

  9. zTree异步生成数据时无法获取到子节点的选中状态

    最近在项目中遇到一个问题,需求如下: 根据选中不同的人员(ID)向后台发送ajax请求,通过返回的数据来生成该人员的权限访问树,该树目录最少为3级目录,在生成的时候会自动勾选上次保存过的选中状态,点击 ...

  10. android:persistent属性

    application PhoneApp既没有被Broadcast唤醒,也没有被其他service调用,那么是android是通过什么方式来启动PhoneApp,所以就发现了属性android:per ...