树链剖分+离散+扫描(HDU5044)
Tree
There are N - 1 edges numbered from 1 to N - 1.
Each node has a value and each edge has a value. The initial value is 0.
There are two kind of operation as follows:
● ADD1 u v k: for nodes on the path from u to v, the value of these nodes increase by k.
● ADD2 u v k: for edges on the path from u to v, the value of these edges increase by k.
After finished M operation on the tree, please output the value of each node and edge.
The first line of each case contains two integers N ,M (1 ≤ N, M ≤105),denoting the number of nodes and operations, respectively.
The next N - 1 lines, each lines contains two integers u, v(1 ≤ u, v ≤ N ), denote there is an edge between u,v and its initial value is 0.
For the next M line, contain instructions “ADD1 u v k” or “ADD2 u v k”. (1 ≤ u, v ≤ N, -105 ≤ k ≤ 105)
The second line contains N integer which means the value of each node.
The third line contains N - 1 integer which means the value of each edge according to the input order.
2
4 2
1 2
2 3
2 4
ADD1 1 4 1
ADD2 3 4 2
4 2
1 2
2 3
1 4
ADD1 1 4 5
ADD2 3 2 4
Case #1:
1 1 0 1
0 2 2
Case #2:
5 0 0 5
0 4 0题意:给出一棵树,树上的点和边的权值开始都是0,有两种操作,对于第一种操作,ADD1:在u到v的路径上每个点的权值+w;对于第二种操作ADD2:在u到v的路径上每个边的权值+w;最后询问每个点的权值和每条边的权值(按照输入的顺序)分析:首先两个dfs进行轻重链剖分,然后对于每个区间[L,R],在L的位置+w,在R+1的位置-w,保存在g1数组中,同理,对于边也一样,保存在g2数组里,最后从前往后做一遍扫描即可;程序:#pragma comment(linker, "/STACK:1024000000,1024000000")
#include"stdio.h"
#include"string.h"
#include"iostream"
#include"map"
#include"string"
#include"queue"
#include"stdlib.h"
#include"algorithm"
#include"math.h"
#define M 110009
#define eps 1e-5
#define inf 100000000
#define mod 100000000
#define INF 0x3f3f3f3f
using namespace std;
struct node
{
int v;
node(int vv){v=vv;}
};
vector<node>edge[M];
int pos,son[M],fa[M],p[M],fp[M],deep[M],top[M],num[M],g1[M],g2[M],ans[M];
void dfs(int u,int f,int d)
{
deep[u]=d;
fa[u]=f;
num[1]=1;
for(int i=0;i<(int)edge[u].size();i++)
{
int v=edge[u][i].v;
if(v==f)continue;
dfs(v,u,d+1);
num[u]+=num[v];
if(son[u]==-1||num[son[u]]<son[v])
son[u]=v;
}
}
void getpos(int u,int sp)
{
top[u]=sp;
p[u]=pos++;
fp[p[u]]=u;
if(son[u]==-1)return;
getpos(son[u],sp);
for(int i=0;i<(int)edge[u].size();i++)
{
int v=edge[u][i].v;
if(v==son[u]||v==fa[u])continue;
getpos(v,v);
}
}
void init()
{
pos=0;
memset(son,-1,sizeof(son));
dfs(1,1,1);
getpos(1,1);
}
void getnode(int u,int v,int d)
{
int f1=top[u];
int f2=top[v];
while(f1!=f2)
{
if(deep[f1]<deep[f2])
{
swap(f1,f2);
swap(u,v);
}
g1[p[f1]]+=d;
g1[p[u]+1]-=d;
u=fa[f1];
f1=top[u];
}
if(u==v)
{
g1[p[u]]+=d;
g1[p[u]+1]-=d;
return;
}
if(deep[u]>deep[v])swap(u,v);
g1[p[u]]+=d;
g1[p[v]+1]-=d;
return;
}
void getedge(int u,int v,int d)
{
int f1=top[u];
int f2=top[v];
while(f1!=f2)
{
if(deep[f1]<deep[f2])
{
swap(f1,f2);
swap(u,v);
}
g2[p[f1]]+=d;
g2[p[u]+1]-=d;
u=fa[f1];
f1=top[u];
}
if(u==v)
return;
if(deep[u]>deep[v])swap(u,v);
g2[p[son[u]]]+=d;
g2[p[v]+1]-=d;
return;
}
struct lede
{
int u,v;
}e[M];
int main()
{
int T,m,n,i,u,v,w,kk=1;
char ch[22];
cin>>T;
while(T--)
{
scanf("%d%d",&n,&m);
for(i=0;i<=n;i++)
edge[i].clear();
for(i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
edge[u].push_back(v);
edge[v].push_back(u);
e[i].u=u;
e[i].v=v;
}
init();
memset(g1,0,sizeof(g1));
memset(g2,0,sizeof(g2));
while(m--)
{
scanf("%s%d%d%d",ch,&u,&v,&w);
if(strcmp(ch,"ADD1")==0)
getnode(u,v,w);
else
getedge(u,v,w);
}
printf("Case #%d:\n",kk++);
int sum=0;
for(i=0;i<pos;i++)
{
sum+=g1[i];
ans[i]=sum;
}
for(i=1;i<=n;i++)
{
if(i==1)
printf("%d",ans[p[i]]);
else
printf(" %d",ans[p[i]]);
}
printf("\n");
sum=0;
for(i=1;i<pos;i++)
{
sum+=g2[i];
ans[i]=sum;
}
for(i=1;i<n;i++)
{
if(deep[e[i].u]<deep[e[i].v])
swap(e[i].u,e[i].v);
if(i==1)
printf("%d",ans[p[e[i].u]]);
else
printf(" %d",ans[p[e[i].u]]);
}
printf("\n");
}
}
树链剖分+离散+扫描(HDU5044)的更多相关文章
- HDU5029--Relief grain (树链剖分+线段树 )
题意:n个点构成的无根树,m次操作, 对于操作 x y z, 表示 x 到 y 路径上的 每个点 加一个 z 数字,可重复加.最后输出每个点 加的次数最多的那个数字,如果没有输出0. 赤裸裸的树链剖分 ...
- HDU 4366 Successor(树链剖分+zkw线段树+扫描线)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4366 [题目大意] 有一个公司,每个员工都有一个上司,所有的人呈树状关系,现在给出每个人的忠诚值和 ...
- HDU - 3966 Aragorn's Story(树链剖分入门+线段树)
HDU - 3966 Aragorn's Story Time Limit: 3000MS Memory Limit: 32768KB 64bit IO Format: %I64d & ...
- LightOJ 1348 (树链剖分 + 线段树(树状数组))
题目 Link 分析 典型的树链剖分题, 树链剖分学习资料 Code #include <bits/stdc++.h> using namespace std; const int max ...
- HDU 5293 Train chain Problem - 树链剖分(树状数组) + 线段树+ 树型dp
传送门 题目大意: 一颗n个点的树,给出m条链,第i条链的权值是\(w_i\),可以选择若干条不相交的链,求最大权值和. 题目分析: 树型dp: dp[u][0]表示不经过u节点,其子树的最优值,dp ...
- BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2050 Solved: 817[Submit][Status ...
- BZOJ 1984: 月下“毛景树” [树链剖分 边权]
1984: 月下“毛景树” Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 1728 Solved: 531[Submit][Status][Discu ...
- codevs 1228 苹果树 树链剖分讲解
题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...
- 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)
题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...
随机推荐
- 关于Unity中的删除、显示和隐藏节点
一.删除节点和组件 1.删除一个节点,以及节点上面所有的组件全部删除了//删除一个节点的时候,节点上面所有的组件也会被删除:MonoBehaviour.Destroy(this.gameObject) ...
- Java 经典问题
九种基本类型及封装类 基本类型 boolean byte char short int long double void 二进制位数 1 8(一字节) 16(2字节) 16(2字节) 32(4字节) ...
- 编译 & 执行 C++ 程序
编译 & 执行 C++ 程序接下来让我们看看如何把源代码保存在一个文件中,以及如何编译并运行它.下面是简单的步骤: 打开一个文本编辑器,添加上述代码.保存文件为 hello.cpp.打开命令提 ...
- linux -- ubuntu 脚本开机自启动
有一个脚本想在ubuntu 虚拟机开机时,自动运行. 创建脚本文件 在“/opt/lampp/”下新建一个脚本文件:lampp_start.sh #!/bin/bash /opt/lampp/lamp ...
- linux -- 常用的20个命令
1. ls命令 ls命令是列出目录内容(List Directory Contents)的意思.运行它就是列出文件夹里的内容,可能是文件也可能是文件夹. root@tecmint:~# ls Andr ...
- struct iphdr中的__LITTLE_ENDIAN_BITFIELD和__BIG_ENDIAN_BITFIELD
__LITTLE_ENDIAN_BITFIELD表示小端序,__BIG_ENDIAN_BITFIELD表示大端序. /usr/include/linux/ip.h中有一段代码定义了ip首部的结构体,例 ...
- JBPM——工作流概念
一.概念 工作流(Workflow),就是"业务过程的部分或总体在计算机应用环境下的自己主动化",它主要解决的是"使在多个參与者之间依照某种提前定义的规 ...
- 腾讯企业邮箱POP,SMTP分别是什么
腾讯企业邮箱在做域名解析的时候不用做pop3和 smtp设置,可以使用下列的协议: POP3/SMTP协议 接收邮件服务器:pop.exmail.qq.com (端口 110),使用SSL,端口号 ...
- Jmeter零起点学习
什么是JMeter Apache JMeter是一个开源的Java桌面软件.设计的目的就是进行C/S架构软件的负载测试.随着发展,有很多人也用来进行一些静态资源或者动态资源的性能测试.可以支持的测 ...
- gevent动态随时添加任务
关于爬虫,有scrapy框架,也有requests加协程 协程 进程的方法. 相关的包很多,比如threading .threadpool.multiprocessing,还有threadpoolex ...