题意:给一棵树,两种操作: ADD1: 给u-v路径上所有点加上值k, ADD2:给u-v路径上所有边加上k,初始值都为0,问最后每个点和每条边的值,输出。

解法:树链剖分可做,剖出来如果直接用线段树来区间更新的话会TLE,所以要换一种姿势,有一种树链剖分的经典姿势就是看做树状数组一样,每次加值的时候,比如u->v之间加一个值k,那么在u处+k,v+1处-k即可,然后扫一遍,每次把当前位置要做的操作做完,此时总共加的值就是当前处的值,扫一遍的时候维护的是前缀的和,也就是两个ans不清零。

这题卡时间太紧,不加读入挂会T,不加输出挂的话跑4921ms,也是飘过,加了输入输出挂才稍微好点,4687ms,可能是树链剖分不够优越

代码:

#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define lll __int64
using namespace std;
#define N 100007 int siz[N]; //子树大小
int son[N]; //重儿子
int dep[N]; //深度
int pos[N],apos[N]; //点在线段树中的位置
int Top[N]; //所在重链的祖先
int fa[N]; //父节点
lll eans[N],nans[N]; //答案
int head[*N],tot,POS,n,m;
struct Edge
{
int v,next;
}G[*N],Qe[*N],Qn[*N];
int heade[*N],headn[*N],tote,totn;
struct node
{
int u,v;
}edge[N]; void init()
{
POS = tot = tote = totn = ;
memset(head,-,sizeof(head));
memset(son,-,sizeof(son));
memset(heade,-,sizeof(heade));
memset(headn,-,sizeof(headn));
} void addedge(int u,int v)
{
G[tot].v = v, G[tot].next = head[u], head[u] = tot++;
G[tot].v = u, G[tot].next = head[v], head[v] = tot++;
} void ADDNedge(int u,int v) //代替vector来存操作
{
Qn[totn].v = v, Qn[totn].next = headn[u], headn[u] = totn++;
} void ADDEedge(int u,int v) //代替vector来存操作
{
Qe[tote].v = v, Qe[tote].next = heade[u], heade[u] = tote++;
} void dfs(int u,int f)
{
dep[u] = dep[f]+;
siz[u] = ;
for(int i=head[u];i!=-;i=G[i].next)
{
int v = G[i].v;
if(v == f) continue;
fa[v] = u;
dfs(v,u);
if(son[u] == - || siz[v] > siz[son[u]]) son[u] = v;
siz[u] += siz[v];
}
} void dfs2(int u,int top)
{
pos[u] = ++POS;
apos[POS] = u;
Top[u] = top;
if(son[u] != -) dfs2(son[u],top);
for(int i=head[u];i!=-;i=G[i].next)
{
int v = G[i].v;
if(v != fa[u] && v != son[u])
dfs2(v,v);
}
} void AddEdge(int u,int v,int k)
{
int fx = Top[u], fy = Top[v];
while(fx != fy)
{
if(dep[fx] < dep[fy])
{
swap(u,v);
swap(fx,fy);
}
ADDEedge(pos[fx],k);
ADDEedge(pos[u]+,-k);
u = fa[fx];
fx = Top[u];
}
if(dep[u] > dep[v]) swap(u,v);
ADDEedge(pos[son[u]],k);
ADDEedge(pos[v]+,-k);
} void AddNode(int u,int v,int k)
{
int fx = Top[u], fy = Top[v];
while(fx != fy)
{
if(dep[fx] < dep[fy])
{
swap(u,v);
swap(fx,fy);
}
ADDNedge(pos[fx],k);
ADDNedge(pos[u]+,-k);
u = fa[fx];
fx = Top[u];
}
if(dep[u] > dep[v]) swap(u,v);
ADDNedge(pos[u],k);
ADDNedge(pos[v]+,-k);
} inline int in()
{
char ch;
int a = ;
while((ch = getchar()) == ' ' || ch == '\n');
a += ch - '';
while((ch = getchar()) != ' ' && ch != '\n')
{
a *= ;
a += ch - '';
}
return a;
} inline void out(lll num){
bool flag=false;
if(num<){
putchar('-');
num=-num;
}
int ans[],top=;
while(num!=){
ans[top++]=num%;
num/=;
}
if(top==)
putchar('');
for(int i=top-;i>=;i--){
char ch=ans[i]+'';
putchar(ch);
}
} int main()
{
int u,v,k,i,j,t,cs = ;
char ss[];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
init();
for(i=;i<n;i++)
{
edge[i].u = in();
edge[i].v = in();
addedge(edge[i].u,edge[i].v);
}
dep[] = ;
dfs(,);
dfs2(,);
while(m--)
{
scanf("%s",ss);
u = in(), v = in(), k = in();
if(ss[] == '') //node
AddNode(u,v,k);
else
AddEdge(u,v,k);
}
printf("Case #%d:\n",cs++);
lll ansedge = ,ansnode = ;
for(i=;i<=n;i++)
{
for(j=headn[i];j!=-;j=Qn[j].next)
ansnode += Qn[j].v;
for(j=heade[i];j!=-;j=Qe[j].next)
ansedge += Qe[j].v;
nans[apos[i]] = ansnode;
eans[apos[i]] = ansedge;
}
for(i=;i<=n;i++)
{
out(nans[i]);
printf("%c",i==n?'\n':' ');
}
for(i=;i<n;i++)
{
int u = edge[i].u, v = edge[i].v;
if(dep[u] > dep[v]) swap(u,v);
out(eans[v]);
printf("%c",i==n-?'\n':' ');
}
if(n == ) puts(""); //PE..
}
return ;
}

HDU 5044 Tree --树链剖分的更多相关文章

  1. HDU 5044 Tree 树链剖分+区间标记

    Tree Problem Description You are given a tree (an acyclic undirected connected graph) with N nodes. ...

  2. HDU 5044 (树链剖分+树状数组+点/边改查)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5044 题目大意:修改链上点,修改链上的边.查询所有点,查询所有边. 解题思路: 2014上海网赛的变 ...

  3. Hdu 5274 Dylans loves tree (树链剖分模板)

    Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...

  4. hdu 5458 Stability(树链剖分+并查集)

    Stability Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)Total ...

  5. POJ3237 Tree 树链剖分 边权

    POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...

  6. HDU 5614 Baby Ming and Matrix tree 树链剖分

    题意: 给出一棵树,每个顶点上有个\(2 \times 2\)的矩阵,矩阵有两种操作: 顺时针旋转90°,花费是2 将一种矩阵替换为另一种矩阵,花费是10 树上有一种操作,将一条路经上的所有矩阵都变为 ...

  7. Tree HDU - 6547 (树链剖分,线段树)

    wls 有三棵树,树上每个节点都有一个值 ai,现在有 2 种操作: 将一条链上的所有节点的值开根号向下取整: 求一条链上值的和: 链的定义是两点之间的最短路. Input 第一行两个数 n, q 分 ...

  8. Query on a tree——树链剖分整理

    树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...

  9. 【BZOJ-4353】Play with tree 树链剖分

    4353: Play with tree Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 31  Solved: 19[Submit][Status][ ...

随机推荐

  1. 写给java程序员的c++与java实现的一些重要细微差别

    0.其实常规的逻辑判断结构.工具类.文件读写.控制台读写这些的关系都不大,熟悉之后,这些都是灵活运用的问题. 学习c/c++需要预先知道的一个前提就是,虽然有ANSI C标准,但是每个c/c++编译器 ...

  2. [WF] Quickstart Sample

    [WF] Quickstart Sample 前言 Workflow Foundation(WF),总是给人一种很有用.可是却不知道怎么用的印象.这主要是因为前置的功课太多.要整合很多底层知识,才能完 ...

  3. SQL对字符串数组的处理详解

    原文地址:SQL字符串数组操作文章出处:DIY部落(http://www.diybl.com/course/7_databases/sql/sqlServer/2007106/76999.html) ...

  4. CSS3选择器(二)--表单

    :enabled 选择可用状态的表单元素 :disabled 选择不可用状态的表单元素 :checked 复选框.单选框选中状态的选项 ::selection 用来匹配突出显示的文本(用鼠标选择文本时 ...

  5. SMW0上传EXCEL模板时报错无分配给对象***的MIME类型

    在使用SMW0上传照片.声音文件.EXCEL模板等文件时,遇到报错提示,如下图所示: 解决办法:需要先维护 .XLS 文件的MIME TYPE,SMW0 打开如下图所示 选择上图红色框中“WebRFC ...

  6. .NET破解之分享给新注册的朋友

    前些日子,在论坛里看了有人发过这个软件,也有大神分析过网络版,如果是重帖,请删除吧:正好11.11注册了很多新会员,给他们一个见面礼吧,抛砖引玉,我才来论坛的时候,也是看着前人教程慢慢学习的:好久没冒 ...

  7. 设置ArcGIS的外观改回到出厂

    在一般的软件中,都可以在工具-选项中打开相关设置将应用程序的外观改回到出厂.但ArcGIS好像没有,但查帮助文档原来是这样: 配置的更改保存在模板文档中(例如,ArcMap 将其更改保存在 Norma ...

  8. Ubuntu上安装Apache、MySql和PHP

    参考文献: http://developer.51cto.com/art/201110/299303.htm

  9. Android项目实战(四):ViewPager切换动画(3.0版本以上有效果)

    学习内容来自“慕课网” 一般APP进去之后都会有几张图片来导航,这里就学习怎么在这张图片切换的时候添加切换动画效果 先看布局文件 activity_main.layout <?xml versi ...

  10. 【转】self.myOutlet=nil、viewDidUnload、dealloc的本质剖析

    对于iphone开发人员来说,内存管理是极为重要的技巧,哪怕程序的功能再强大,设计再漂亮,如果内存控制不好,也难逃程序莫名退出的噩运,这与网页开发是完全不同的. 内存控制里面有很多门道,在这里分析一下 ...