数据结构(动态树):[国家集训队2012]tree(伍一鸣)
【问题描述】
+ 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-1行每行两个正整数u,v,描述这棵树
接下来q行,每行描述一个操作
【输出格式】
【样例输入】
1 2
2 3
* 1 3 4
/ 1 1
【样例输出】
【数据规模和约定】
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(伍一鸣)的更多相关文章
- [COGS 1799][国家集训队2012]tree(伍一鸣)
Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2 ...
- cogs1799 [国家集训队2012]tree(伍一鸣)
LCT裸题 注意打标记之间的影响就是了 这个膜数不会爆unsigned int #include<cstdio> #include<cstdlib> #include<a ...
- [国家集训队2012]tree(陈立杰)
[国家集训队2012]tree(陈立杰) 题目 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树.题目保证有解. INPUT 第一行V,E,need分别表示 ...
- [国家集训队2012]tree(陈立杰) 题解(二分+最小生成树)
tree 时间限制: 3 Sec 内存限制: 512 MB 题目描述 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解. 输入 第一行V, ...
- [国家集训队2012]middle
http://cogs.pro:8080/cogs/problem/problem.php?pid=1763 二分答案x 把区间内>=x的数设为1,<x的数设为-1 左端点在[a,b]之间 ...
- [国家集训队2012]JZPFAR
[国家集训队2012]JZPFAR 题目 平面上有n个点.现在有m次询问,每次给定一个点(px, py)和一个整数k,输出n个点中离(px, py)的距离第k大的点的标号.如果有两个(或多个)点距离( ...
- luogu P2619 [国家集训队2]Tree I
题目链接 luogu P2619 [国家集训队2]Tree I 题解 普通思路就不说了二分增量,生成树check 说一下坑点 二分时,若黑白边权有相同,因为权值相同优先选白边,若在最有增量时出现黑白等 ...
- P2619 [国家集训队2]Tree I(最小生成树+二分)
P2619 [国家集训队2]Tree I 每次二分一个$x$,每条白边加上$x$,跑最小生成树 统计一下满足条件的最小值就好了. to me:注意二分不要写挂 #include<iostream ...
- Luogu P2619 [国家集训队2]Tree I(WQS二分+最小生成树)
P2619 [国家集训队2]Tree I 题意 题目描述 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有\(need\)条白色边的生成树. 题目保证有解. 输入输出格式 输入格式 ...
随机推荐
- Java——(七)Map之HashMap和Hashtable实现类
------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- Map Map用于具有映射关系的数据,因此Map集合里保存着两组值,一组值用于保存Map里的ke ...
- Bash远程文件传输命令scp
备份远程文件(远程——>本地) scp -r 远程用户名@ip:文件绝对路径 本地绝对路径 还原远程文件(本地——>远程) scp -r 本地路径 远程用户名@ip:远程绝对路径 如果SS ...
- python版本简历
- Android4.0的Alertdialog对话框,设置点击其他位置不消失
Android4.0以上AlertDialog,包括其他自定义的dialog,在触摸对话框边缘外部,对话框消失. 可以设置这么一条属性,当然必须先AlertDialog.Builder.create( ...
- jquery parseInt()的问题
对于parseInt("01")到parseInt("07");都能得到正确的结果,但如果是parseInt("08") 或parseInt ...
- 如何用visual studio控件(repeater)绑定数据库(SQL server)信息并显示
今天学习了下如何间接绑定数据库网上看了很多信息,都云里雾里,没有图片说明,初学者完全看不懂,我自己做了一个DEMO,相信可以帮到大家! 一.建立数据库,并构建表信息,我的表信息如下: 表中的数据在数据 ...
- 十六、C# 常用集合类及构建自定义集合(使用迭代器)
常用集合类及构建自定义集合 1.更多集合接口:IList<T>.IDictionary<TKey,TValue>.IComparable<T>.ICollectio ...
- 07ADO.Net
1.ADO.Net简介 代码示例: using (MySqlConnection conn = new MySqlConnection("Server=localhost;Database= ...
- SGU 162.Pyramids
时间限制:0.25s 空间限制:6M; 题意: 按照AB, AC, AD, BC, BD, CD.给出一个空间四面体的6条边长.求出它的体积. Solution: 欧拉四面体公式: ...
- 【HDU4391】【块状链表】Paint The Wall
Problem Description As a amateur artist, Xenocide loves painting the wall. The wall can be considere ...