【问题描述】

一棵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. Objective-C:属性(@property)

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  2. ubuntu下的openfire安装、配置、运行

    openfire服务器              Openfire 采用Java开发,开源的实时协作(RTC)服务器基于XMPP(Jabber)协议.您可以使用它轻易的构建高效率的即时通信服务器.Op ...

  3. 用CSS+Jquery实现一个漂浮的窗体

    一.项目需求: 实现一个用于网站主页面 从窗体左上角开始飘到右下角 之后又飘到右上角 十秒之后消失的效果. 二.需求分析: 首先 应当想要漂浮的内容放在一个容器内,也就是一个DIV,设计它的样式,不管 ...

  4. JS中的事件绑定,事件捕获,事件冒泡以及事件委托,兼容IE

    转载请注明出处:http://www.cnblogs.com/zhangmingze/p/4864367.html   ● 事件分为三个阶段:   事件捕获 -->  事件目标 -->   ...

  5. hibernate对象关系映射( 一对一,一对多,多对一,多对多的单向,双向映射 ——)

    对象之间的关系: 关系映射之间的关系只的是对象之间的关系,并不指数据库表的关系(外键关系)这儿解决的问题是当对象之间的关系之一时,数据库表该如何映射,编程上如何对待. 一对一(主键关联,和单向的外键关 ...

  6. Datatables+Bootstrap

    http://sandbox.runjs.cn/show/thwac3ec 运行效果 <!DOCTYPE html> <html lang="en"> &l ...

  7. wpf 自定义RadioButton控件样式

    实现的效果为: 我感觉来自定义RadioButton样式和定义button空间的样式差不多,只是类型不同而已. 接下来分析一下样式代码: <!--自定义单选按钮样式-->        & ...

  8. group by应用

    注意: having是对分组后的数据进行第二次筛选或者过滤,也就是说没有group by就没having where之后不能有聚合函数 查询每个年级的总学时数,并按照升序排列select GradeI ...

  9. C++函数二义性问题,我怎么感觉编译器有偷懒嫌疑!!!

    瞎扯一段,讲得不一定对.纯属学习! struct BB{ void a(){ cout << "bb's a()\n"; }}; struct B1 : public ...

  10. vs2008 下编译jrtplib-3.9.0成功

    jrtplib-3.9.0的编译,终于搞通了.网上搜集了很多资料,自己也调试了很久. 首先,jrtplib-3.9.0是什么不用多说吧,它是一个很牛的老外用C++写的一个开源的RTP协议库,用它可以进 ...