题意:给一棵树,两种操作: 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. ASP.NET WebAPI 12 Action的执行

    Action的激活大概可以分为如下两个步骤:Action对应方法的调用,执行结果的协商.在WebAPI中由HttpActionInvoker(System.Web.Http.Controllers)进 ...

  2. Mvc下异步断点续传大文件

    最近公司一同事咨询了一个MVC项目下上传大文件时遇到的问题,问题描述如下: MVC项目中,当上传比较大的文件时,速度非常慢,小文件基本没有影响. 原因分析: 如果是用传统的form表单去提交的话,会将 ...

  3. C语言动态调用库(转)

    转自:http://cloverprince.iteye.com/blog/481309 现有一个主程序用C语言写成.现在要允许第三方开发人员编写扩展的模块,约定第三方开发的模块必须提供一系列已知名称 ...

  4. online judge(ACM) 的设计与分析 (有c#demo)

    ACM.OJ,算法在线判题系统. 帮朋友完成毕业设计而写的,软件环境windows系统,语言是C# winform(因为我不熟悉asp.net,现在暂用winform写的demo). 看了下其他相关论 ...

  5. wpf 窗口程序下将datagrid导出为excel

    今天用了几个小时也没有找到将datagrid导出为excel的方法,搜索msdn发现,老外也木有解决这个问题,因此把代码贴出来,和大家分享一下,提高工作效率.简要说一哈,本程序使用反射,因此代码量看起 ...

  6. javascript小知识点

    大家对input中的value值研究的透彻么,今天看到一篇博客,很神奇  然后研究了一下input中的value值到底对应的是啥值 1.input中的value,这是大家在开发中进场遇到的一个问题 & ...

  7. 浅谈DES加密算法

    一.DES加密算法介绍 1.要求密钥必须是8个字节,即64bit长度 2.因为密钥是byte[8] , 代表字符串也可以是非可见的字节,可以与Base64编码算法一起使用 3.加密.解密都需要通过字节 ...

  8. Android ListView用EditText实现搜索功能

    前言 最近在开发一个IM项目的时候有一个需求就是,好友搜索功能.即在EditText中输入好友名字,ListView列表中动态展示刷选的好友列表.我把这个功能抽取出来了,先贴一下效果图: 分析 在查阅 ...

  9. Swift开发第四篇——柯里化

    本篇分为两部分: 一.柯里化的基本使用 二.柯里化的使用场景 一.柯里化的基本使用 柯里化(Currying):也就是把接受多个参数的方法变换成接受第一个参数的方法,并且返回接受余下的参数并且返回结果 ...

  10. 实验:传输层:TCP协议

    一.概述 TCP和UDP处在同一层——运输层,但是它们有很多的不同.TCP是TCP/IP系列协议中最复杂的部分,它具有以下特点: (1) TCP提供 可靠的 数据传输服务,TCP是 面向连接的 .应用 ...