题意:n个点构成的无根树,m次操作, 对于操作 x y z, 表示 x 到 y 路径上的 每个点 加一个 z 数字,可重复加。最后输出每个点 加的次数最多的那个数字,如果没有输出0.

赤裸裸的树链剖分,可是剖分之后 怎么用线段树维护每个点加的数字的次数呢。这里用到的思想类似于2014年上海网络赛的一道题。HDU5044,假如[x,y]这个区间上所有的点加上数字z,可以用两个标记 vec[x] + z,vec[y+1] -c。HDU上C++提交竟然爆栈,不过G++还是顺利ac了。具体见代码

 #include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1e5+;
int siz[maxn],dep[maxn],son[maxn],fa[maxn];
struct
{
int to,next;
}e[maxn<<];
int tot,head[maxn];
void add_edge(int x,int y)
{
e[tot].to = y;
e[tot].next = head[x];
head[x] = tot++;
}
void dfs(int r)
{
son[r] = ;
siz[r] = ;
for (int i = head[r]; ~i; i = e[i].next)
{
int u = e[i].to;
if (fa[r] != u)
{
dep[u] = dep[r] + ;
fa[u] = r;
dfs(u);
if (siz[u] > siz[son[r]])
son[r] = u;
siz[r] += siz[u];
}
}
}
int top[maxn],pos[maxn],fp[maxn],idx;
void build(int r,int father)
{
pos[r] = ++idx; //记录每一个点 对应的位置
fp[pos[r]] = r; //记录每一个位置对应的点
top[r] = father;
if (son[r] > )
build(son[r],top[r]);
for (int i = head[r]; ~i; i = e[i].next)
{
if (fa[r] != e[i].to && son[r] != e[i].to)
build(e[i].to,e[i].to);
}
}
vector<int>vec[maxn];
void update(int x,int y,int v)
{
int fx = top[x];
int fy = top[y];
while (fx != fy)
{
if (dep[fx] < dep[fy])
{
swap(x,y),swap(fx,fy);
}
vec[pos[fx]].push_back(v); //有点类似于树状数组区间更新单点查询,
vec[pos[x] + ].push_back(-v);
x = fa[fx];
fx = top[x];
}
if (dep[x] > dep[y])
swap(x,y);
vec[pos[x]].push_back(v);
vec[pos[y] + ].push_back(-v);
} int n,m,seg[maxn<<],max_pos[maxn<<]; //max_pos为最大值在原始数组中的位置
void init()
{
int root = (+n)/;
idx = tot = ;
dep[root] = fa[root] = ;
memset(head,-,sizeof(head));
memset(siz,,sizeof(siz));
memset(seg,,sizeof(seg));
memset(max_pos,,sizeof(max_pos));
for (int i = ; i < n - ; i++)
{
int u,v;
scanf ("%d%d",&u,&v);
add_edge(u,v);
add_edge(v,u);
}
dfs(root);
build(root,root);
for (int i = ; i <= n; i++)
vec[i].clear();
for (int i = ; i < m; i++)
{
int x,y,v;
scanf ("%d%d%d",&x,&y,&v);
update(x,y,v);
}
}
void update(int l,int r,int pos,int x,int val)
{
if (l == r)
{
seg[pos] += val;
if (seg[pos] > )
max_pos[pos] = l;
else
max_pos[pos] = ;
return;
}
int mid = (l + r) >> ;
if (x <= mid)
update(l,mid,pos<<,x,val);
else
update(mid+,r,pos<<|,x,val);
if (seg[pos<<] >= seg[pos<<|])
{
seg[pos] = seg[pos<<];
max_pos[pos] = max_pos[pos<<];
}
else
{
seg[pos] = seg[pos<<|];
max_pos[pos] = max_pos[pos<<|];
}
}
int ans[maxn];
void solve()
{
for (int i = ; i <= n; i++)
{
for (unsigned int j = ; j < vec[i].size(); j++)
{
if (vec[i][j] > )
update(,maxn,,vec[i][j],);
else
update(,maxn,,-vec[i][j],-);
}
ans[fp[i]] = max_pos[];
}
for (int i = ; i <= n; i++)
printf("%d\n",ans[i]); }
int main(void)
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
while (~scanf ("%d%d",&n,&m))
{
if ((n == ) && (m == ))
break;
init();
solve();
}
return ;
}

HDU5029--Relief grain (树链剖分+线段树 )的更多相关文章

  1. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  2. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  3. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  4. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  5. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  6. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  7. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  8. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

  9. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  10. bzoj2243[SDOI2011]染色 树链剖分+线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9012  Solved: 3375[Submit][Status ...

随机推荐

  1. NS2仿真:公交车移动周期模型及性能分析

    NS2仿真实验报告3 实验名称:公交车移动周期模型及性能分析 实验日期:2015年3月16日~2015年3月21日 实验报告日期:2015年3月22日 一.实验环境(网络平台,操作系统,网络拓扑图) ...

  2. 美洽SDK

    简介 GitHub地址:https://github.com/Meiqia/MeiqiaSDK-Android 开发文档:http://meiqia.com/docs/meiqia-android-s ...

  3. Java多线程——线程同步

    在之前,已经学习到了线程的创建和状态控制,但是每个线程之间几乎都没有什么太大的联系.可是有的时候,可能存在多个线程多同一个数据进行操作,这样,可能就会引用各种奇怪的问题.现在就来学习多线程对数据访问的 ...

  4. 母函数&&排列(模板)

    #include <iostream> #include <algorithm> using namespace std; int main() { int n,i; int ...

  5. CI框架深入篇(2)一些基础的我之不知道的标准格式

    1,一些命名规则:类文件名必大写,其他配置文件,视图文件或着脚本都要小写,类文件名和类名要一致!! 2,类名要大写开头,若是多个单词,那就下划线不要驼封法: 3,变量名要小写全,多个单词下划线分割,后 ...

  6. CSS3 3D转换

    CSS3允许你使用3D转换来对元素进行格式化. 3D转换方法: rotateX() rotateY() 浏览器支持 属性 浏览器支持 transform           IE10和Firefox支 ...

  7. 安装ORACLE 11g 64位 pl/sql无法进入的问题。

    转载自网上的内容: 1)安装Oracle 11g 64位 2)安装32位的Oracle客户端( instantclient-basic-win32-11.2.0.1.0)下载地址:http://www ...

  8. SQL Server 分组后取Top N

    SQL Server 分组后取Top N(转) 近日,工作中突遇一需求:将一数据表分组,而后取出每组内按一定规则排列的前N条数据.乍想来,这本是寻常查询,无甚难处.可提笔写来,终究是困住了笔者好一会儿 ...

  9. 通过安全策略限制局域网部分IP访问我的电脑

    一旦电脑连上局域网,那么别人就容易进入自己的电脑,造成隐私被泄漏,这是我们最不愿发生的情况.因此,如果你的电脑并不需要向局域网其他用户共享资料,那么就建议采用策略,禁止局域网电脑访问自己的电脑,以保证 ...

  10. javascript sort()与reverse()

    javascript 中提供了两个对数据进行排序的方法,即sort()和reverse() 在理解的时候犯了一个非常低级的错误,现记录如下: reverse()不包括排序的功能,只是把原来的数组反转. ...