题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5044

题目大意:修改链上点,修改链上的边。查询所有点,查询所有边。

解题思路

2014上海网赛的变态树链剖分模板题。将以往树链剖分的点&边修改和查询合在一起之后,难度上去不少。

第一个卡人点是读入优化。

第二个卡人点是树状数组。由于要查询所有点,如果使用线段树,每次都要扫到底层才能取出点值,必T无疑。

然后使用树状数组之后,树链剖分的点/边修改写法有些变动。

点查询变化不大。

边查询只要查询一下dep(u,v)大的那一端。

具体变化请仔细看代码。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include "cstdio"
#include "cstring"
#include "iostream"
using namespace std;
#define maxn 100005
template <class T>
inline bool read(T &ret)
{
char c;
int sgn;
if(c=getchar(),c==EOF) return ; //EOF
while(c!='-'&&(c<''||c>'')) c=getchar();
sgn=(c=='-')?-:;
ret=(c=='-')?:(c-'');
while(c=getchar(),c>=''&&c<='') ret=ret*+(c-'');
ret*=sgn;
return ;
}
int s[maxn],dep[maxn],w[maxn],fa[maxn],top[maxn],son[maxn],tol,cnt,n,head[maxn];
struct Edge
{
int u,v,c;
}edge[maxn];
struct EDGE
{
int next,to;
}e[*maxn];
void addedge(int u,int v)
{
e[tol].to=v;
e[tol].next=head[u];
head[u]=tol++;
}
void dfs1(int u,int pre,int d)
{
s[u]=;fa[u]=pre;dep[u]=d;son[u]=-;
for(int i=head[u];i!=-;i=e[i].next)
{
int v=e[i].to;
if(v==pre) continue;
dfs1(v,u,d+);
s[u]+=s[v];
if(son[u]!=-||s[v]>s[son[u]]) son[u]=v;
}
}
void dfs2(int u,int tp)
{
w[u]=++cnt;top[u]=tp;
if(son[u]!=-) dfs2(son[u],tp);
for(int i=head[u];i!=-;i=e[i].next)
{
int v=e[i].to;
if(v!=son[u]&&v!=fa[u]) dfs2(v,v);
}
}
//Binary-Indexed-Tree type:0-point,1-edge
int psum[maxn],esum[maxn];
inline int lowbit(int x) {return x&(-x);}
int sum(int x,int type)
{
int ret=;
while(x>)
{
if(!type) ret+=psum[x];
else ret+=esum[x];
x-=lowbit(x);
}
return ret;
}
void add(int x,int d,int type)
{
while(x<=n)
{
if(!type) psum[x]+=d;
else esum[x]+=d;
x+=lowbit(x);
}
}
void p_Change(int x,int y,int v)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
add(w[top[x]],v,);
add(w[x]+,-v,);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
add(w[x],v,);
add(w[y]+,-v,);
}
void e_Change(int x,int y,int v)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
add(w[top[x]],v,);
add(w[x]+,-v,);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
if(x!=y) //这个判断非常重要,没有的话T死你
{
add(w[son[x]],v,);
add(w[y]+,-v,);
}
}
int main()
{
//freopen("in.txt","r",stdin);
int T,u,v,c,m,no=;
char cmd[];
read(T);
while(T--)
{
memset(head,-,sizeof(head));
memset(esum,,sizeof(esum));
memset(psum,,sizeof(psum));
tol=cnt=;
read(n);read(m);
for(int i=;i<n;i++)
{
read(edge[i].u);read(edge[i].v);
addedge(edge[i].u,edge[i].v);
addedge(edge[i].v,edge[i].u);
}
dfs1(,,);
dfs2(,);
for(int i=;i<n;i++)
if(dep[edge[i].u]<dep[edge[i].v]) swap(edge[i].u,edge[i].v);
while(m--)
{
scanf("%s",cmd);
read(u);read(v);read(c);
if(cmd[]=='') p_Change(u,v,c);
if(cmd[]=='') e_Change(u,v,c);
}
printf("Case #%d:\n",++no);
for(int i=;i<=n;i++) {if(i>=) printf(" ");printf("%d",sum(w[i],));}
printf("\n");
for(int i=;i<n;i++) {if(i>=) printf(" ");printf("%d",sum(w[edge[i].u],));}
printf("\n");
}
}
11824525 2014-10-08 17:34:00 Accepted 5044 3718MS 11576K 3384 B C++ Physcal

HDU 5044 (树链剖分+树状数组+点/边改查)的更多相关文章

  1. hdu 3966 Aragorn's Story(树链剖分+树状数组/线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: 给出一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路 ...

  2. Aragorn's Story 树链剖分+线段树 && 树链剖分+树状数组

    Aragorn's Story 来源:http://www.fjutacm.com/Problem.jsp?pid=2710来源:http://acm.hdu.edu.cn/showproblem.p ...

  3. 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释

    P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...

  4. HDU 3966 Aragorn's Story 树链剖分+树状数组 或 树链剖分+线段树

    HDU 3966 Aragorn's Story 先把树剖成链,然后用树状数组维护: 讲真,研究了好久,还是没明白 树状数组这样实现"区间更新+单点查询"的原理... 神奇... ...

  5. hdu 3966 Aragorn&#39;s Story(树链剖分+树状数组)

    pid=3966" target="_blank" style="">题目链接:hdu 3966 Aragorn's Story 题目大意:给定 ...

  6. HDU 3966 /// 树链剖分+树状数组

    题意: http://acm.hdu.edu.cn/showproblem.php?pid=3966 给一棵树,并给定各个点权的值,然后有3种操作: I x y z : 把x到y的路径上的所有点权值加 ...

  7. HDU 3966 Aragorn's Story (树链剖分+树状数组)

    Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  8. HDU 5293 Train chain Problem - 树链剖分(树状数组) + 线段树+ 树型dp

    传送门 题目大意: 一颗n个点的树,给出m条链,第i条链的权值是\(w_i\),可以选择若干条不相交的链,求最大权值和. 题目分析: 树型dp: dp[u][0]表示不经过u节点,其子树的最优值,dp ...

  9. bzoj1146整体二分+树链剖分+树状数组

    其实也没啥好说的 用树状数组可以O(logn)的查询 套一层整体二分就可以做到O(nlngn) 最后用树链剖分让序列上树 #include<cstdio> #include<cstr ...

随机推荐

  1. 压缩 javascript 和 css

    www.iwangzheng.com 目前我们项目中的 CSS/JS 文件比较多, 由于RAILS 3.0 没有提供asset pipeline功能,所以这样会制约我们的访问速度. 例如:  目前,我 ...

  2. 极客教学:如何使用树莓派击落&劫持无人机

    本教程的目的是帮助大家理解如何研究未受保护的无线通信的安全风险所在,同时我们希望大家不要对技术进行滥用.我们这里采用的例子是一个流行的无人机模型:Parrot AR.Drone 2.0. 四轴无人机能 ...

  3. Ubuntu 14.04/14.10下安装VMware Workstation 11图文教程

    VMware workstation 是一个可以进行桌面操作的虚拟软件.它可以让我们在一台电脑或者虚拟机中运行多个虚拟机. 由VMware公司研发和维护.由于是商业软件,我们需要买他们家的许可证或者说 ...

  4. web页面版权部分的显示问题

    网站开发中绝大部分页面底部都需要版权信息,一般都是Copyright ©域名 2014 - 2015. All Rights Reserved.这种格式,当然也有其他的,有时候不太注意会发现做出的这个 ...

  5. Java for LeetCode 165 Compare Version Numbers

    Compare two version numbers version1 and version2.If version1 > version2 return 1, if version1 &l ...

  6. Java for LeetCode 164 Maximum Gap

    Given an unsorted array, find the maximum difference between the successive elements in its sorted f ...

  7. 19.python笔记之Rabbitmq

    RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议. MQ全称为Message Queue, 消息队列(MQ)是一种应用程序 ...

  8. CodeForces - 417B (思维题)

    Crash Time Limit: 1000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Submit Status ...

  9. Java Hour 20 Spring

    有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. 本文作者Java 现经验约为20 Hour,请各位不吝赐教. 今天心情不佳,只 ...

  10. 解决:jquery-1.11.1.min.js红叉问题

    工程中导入jquery-1.11.1.min.js,工程正常运行.但是jquery-1.11.1.min.js一直显示红叉. 解决方法如下: 红叉的原因是:myeclipse没有去验证它! 选中js文 ...