[hdu3966]Aragorn's Story
题目描述
Our protagonist is the handsome human prince Aragorn comes from The Lord of the Rings. One day Aragorn finds a lot of enemies who want to invade his kingdom. As Aragorn knows, the enemy has N camps out of his kingdom and M edges connect them. It is guaranteed that for any two camps, there is one and only one path connect them. At first Aragorn know the number of enemies in every camp.
But the enemy is cunning , they will increase or decrease the number of soldiers in camps. Every time the enemy change the number of soldiers, they will set two camps C1 and C2. Then, for C1, C2 and all camps on the path from C1 to C2, they will increase or decrease K soldiers to these camps. Now Aragorn wants to know the number of soldiers in some particular camps real-time.
题目大意
三种操作:
- 点\(x\)到点\(y\)的路径上的每一个点的权值都+\(v\)
- 点\(x\)到点\(y\)的路径上的每一个点的权值都-\(v\)
- 查询点\(u\)的权值
解法
树链剖分的模板题,拿过来随便练练手。
我会在第4将的xio讲堂上详细讲解树剖,这里就稍微介绍一下。
树剖在沃的理解上,就是将一棵树通过dfs序或者其他的顺序,和轻重关系来展开到一个一位数组中,然后我们将各个在树上的操作变成一位的操作,这种操作就只需要用数据结构来维护就可以了。
那么反观这道题,我们就将树展开到一维上,并且用线段树来维护,其实非常好理解。
ac代码
#include<bits/stdc++.h>
#define ms(a,b) memset(a,b,sizeof(a))
#define N 50005
#define M 50005
using namespace std;
struct edge{
int to,nt;
}E[M<<1];
int H[N],a[N],val[N],sz[N],dep[N],son[N],top[N],idx[N],fa[N];
int cnt,tot,n,m,p;
int read(){
int w=0,x=0;char ch=0;
while(!isdigit(ch))w|=ch=='-',ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return w?-x:x;
}
void addedge(int u,int v){
E[++cnt]=(edge){v,H[u]}; H[u]=cnt;
}
struct segment_tree{//线段树的各个操作,比较简单不多做讲解
#define lson (nod<<1)
#define rson (nod<<1|1)
#define mid (l+r>>1)
int tr[N<<2],add[N<<2];
void init(){
ms(tr,0);ms(add,0);
}
void pushup(int nod){
tr[nod]=tr[lson]+tr[rson];
}
void pushdown(int l,int r,int nod){
if(!add[nod]) return;
tr[lson]+=add[nod]*(mid-l+1);
tr[rson]+=add[nod]*(r-mid);
add[lson]+=add[nod];
add[rson]+=add[nod];
add[nod]=0;
}
void build(int l,int r,int nod,int *a){
if(l>=r){
tr[nod]=a[l];
return;
}
build(l,mid,lson,a);
build(mid+1,r,rson,a);
pushup(nod);
}
void update(int l,int r,int ql,int qr,int v,int nod){
if(ql<=l&&r<=qr){
tr[nod]+=v*(r-l+1);
add[nod]+=v;
return;
}
pushdown(l,r,nod);
if(ql<=mid) update(l,mid,ql,qr,v,lson);
if(qr>mid) update(mid+1,r,ql,qr,v,rson);
pushup(nod);
}
int query(int l,int r,int k,int nod){
if(l==r) return tr[nod];
pushdown(l,r,nod);
if(k<=mid) return query(l,mid,k,lson);
else return query(mid+1,r,k,rson);
}
}T;
void dfs1(int u,int ft,int dp){//第一遍dfs,求出sz,fa,dep。
sz[u]=1;
fa[u]=ft;
dep[u]=dp;
int maxson=-1;
for(int e=H[u];e;e=E[e].nt){
int v=E[e].to;
if(v==fa[u]) continue;
dfs1(v,u,dp+1);
sz[u]+=sz[v];
if(sz[v]>maxson) maxson=sz[v],son[u]=v;
}
}
void dfs2(int u,int tp){//第二遍dfs,求出idx,val,top,和将各个重点连成重边
idx[u]=++tot;
val[tot]=a[u];
top[u]=tp;
if(!son[u]) return;
dfs2(son[u],tp);
for(int e=H[u];e;e=E[e].nt){
int v=E[e].to;
if(v==fa[u]||v==son[u]) continue;
dfs2(v,v);
}
}
void init(){
cnt=0,tot=0;
ms(son,0);ms(E,0);ms(H,0);ms(top,0);ms(sz,0);ms(idx,0);ms(val,0);
}
int point_query(int u){return T.query(1,n,idx[u],1);}
void chain_update(int u,int v,int w){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
T.update(1,n,idx[top[u]],idx[u],w,1);
u=fa[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
T.update(1,n,idx[u],idx[v],w,1);
}
int main(){
while(~scanf("%d%d%d",&n,&m,&p)){
T.init(); init();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=m;i++) {
int u=read(),v=read();
addedge(u,v);
addedge(v,u);
}
dfs1(1,-1,1);
dfs2(1,1);
T.build(1,n,1,val);
while(p--){
char opt[5];
scanf("%s",opt);
if(opt[0]=='Q'){
int x=read();
printf("%d\n",point_query(x));
}
if(opt[0]=='I'){
int x=read(),y=read(),z=read();
chain_update(x,y,z);
}
if(opt[0]=='D'){
int x=read(),y=read(),z=read();
chain_update(x,y,-z);
}
}
}
return 0;
}
[hdu3966]Aragorn's Story的更多相关文章
- 树链剖分入门-Hdu3966 Aragorn's Story
AC通道:http://acm.hdu.edu.cn/showproblem.php?pid=3966 [题目大意] 一棵树上每个点有权值,每次支持三种操作:给[a,b]路径上的所有节点的权值加上k, ...
- hdu3966 Aragorn's Story 树链剖分
题目传送门 题目大意: 有n个兵营形成一棵树,给出q次操作,每一次操作可以使两个兵营之间的所有兵营的人数增加或者减少同一个数目,每次查询输出某一个兵营的人数. 思路: 树链剖分模板题,讲一下树链剖分过 ...
- Aragorn's Story(hdu3966)
题意:给一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路径上的所有点权值加上K D C1 C2 K:把C1与C2的路径上的所有点权值减去K Q C:查询节点编号为C ...
- 【hdu3966】Aragorn's Story
题意:给一棵树,并给定各个点权的值,然后有3种操作:I C1 C2 K: 把C1与C2的路径上的所有点权值加上KD C1 C2 K:把C1与C2的路径上的所有点权值减去KQ C:查询节点编号为C的权值 ...
- hdu3966 点权模板-树链部分
Aragorn's Story Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 3966 Aragorn's Story (树链剖分+树状数组)
Aragorn's Story Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 3966 Aragorn's Story 树链剖分+树状数组 或 树链剖分+线段树
HDU 3966 Aragorn's Story 先把树剖成链,然后用树状数组维护: 讲真,研究了好久,还是没明白 树状数组这样实现"区间更新+单点查询"的原理... 神奇... ...
- hdu 3966 Aragorn's Story 树链剖分 按点
Aragorn's Story Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU3966(树链剖分)
题目:Aragorn's Story 题意:给一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路径上的所有点权值加上K D C1 C2 K:把C1与C2的路径上的所有 ...
随机推荐
- asp.net mvc 实现上传文件带进度条
本文乃是博主早期写的,此种思路虽然实现了,但固然不是最好的,仅做参考学习. 可以用js onprogress .fileinput .webuploader.jq ajaxsubmit等实现 思路:a ...
- 如何用区块链技术解决信任问题?Fabric 架构深度解读
阿里妹导读:区块链技术,随着比特币的兴起而为大家所知.但是具体到技术本身,大家相对熟悉的几个词可能是“数据不可篡改”.“公开链”.“分布式数据”.“共识机制”等. 这篇文章将抛砖引玉,通过深度解读Hy ...
- (11)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- Thrift高效通讯 (完结)
一. 什么是 RPC Restful 采用 Http 进行通讯,优点是开放.标准.简单.兼容性升级容易: 缺点是性能略低.在 QPS 高或者对响应时间要求苛刻的服务上,可以用 RPC(Remote P ...
- iphone忘记锁屏密码却记得appleID密码的不保存数据的刷机办法
请注意看清题目再看本文,另外一切后果博主不负任何责任.操作实现环境:原装数据线,拔掉sim卡昨天,iPhone6sp忘记密码被锁定,尝试通过找回手机抹除手机功能后,提示需要手机接入互联网才能实现,而我 ...
- 关于Win10下IE11只能以管理员身份运行的处理方式
今天无意间发现IE无法启动,后来研究发现只有用管理员身份运行才能打开,初步分析应该是用户权限的问题,在网上百度了一番,找到了处理的方法,在此分享一下 1.win+R 调出“运行”命令,输入“reged ...
- MongoDB集群运维笔记
前面的文章介绍了MongoDB副本集和分片集群的做法,下面对MongoDB集群的日常维护操作进行小总结: MongDB副本集故障转移功能得益于它的选举机制.选举机制采用了Bully算法,可以很方便从分 ...
- apache工作模式总结及网站访问缓慢处理记录
apache目前主要有两种模式:prefork模式和worker模式:1)prefork模式(默认模式)prefork是Unix平台上的默认(缺省)MPM,使用多个子进程,每个子进程只有一个线程.每个 ...
- C++编写四则运算生成程序
1.计划方案 按照预定计划,在时限为一周时,完成该程序所需时间大致如下表: PSP2.1 Personal Software Process Stages Time Planning 计划 · Est ...
- linux 第七周 总结及实验
姬梦馨 原创作品 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 第七周 Linux内核如何装载和启动一 ...
- elastic-search-kibana-in-docker-dotnet-core-app
[翻译] 使用ElasticSearch,Kibana,ASP.NET Core和Docker可视化数据 原文地址:http://www.dotnetcurry.com/aspnet/1354/e ...