LWDB
题意:
给一棵 $n$ 个节点的树,维护两种操作:
1.将距离 $x$ $distance \leq d$ 的点染成 $c$
2.询问 $x$ 的颜色。
解法:
首先将染色可以转换为每个时间对应一个颜色,问题转化为区间取 $max$
动态树分治,即可。
考虑朴素点分治中的每一个重心,将其管辖的所有点按照到重心的距离从大到小排序,然后用线段树维护。
修改时,从 $x$ 向上走,将每一个重心 $t$ 中 $dist<x,t> + dist<t,y>\leq d$ 的点修改。
查找时,从 $x$ 向上走,查询每一个重心中 $x$ 所对应的值,求 $max$ 即可。
$O(nlog^2n)$
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm> #define p E[i].x
#define N 100010
#define M 7000010
#define l(x) ch[x][0]
#define r(x) ch[x][1]
#define MP(x, y) make_pair(x, y)
#define LL long long using namespace std; typedef pair<int,int> PII; struct edge
{
int x, to, v;
}E[N<<]; int totE, totn, n, m, hev, lef_now;
int g[N], h[N], de[N], siz[N], root[N], fa[N][], col[N], d[N];
int ch[M][], setv[M];
vector<PII> nod[N], id[N];
vector<int> hevs[N];
int dis[N][];
bool v[N]; void addedge(int x, int y, int v)
{
E[++totE] = (edge){y, g[x], v}; g[x] = totE;
} int build(int l, int r)
{
int x = ++totn;
setv[x] = ;
if(l == r) return x;
int mid = (l+r)>>;
l(x) = build(l, mid);
r(x) = build(mid+, r);
return x;
} void push(int x)
{
if(!setv[x]) return;
setv[l(x)] = setv[x];
setv[r(x)] = setv[x];
setv[x] = ;
} int ask(int x, int l, int r, int qx)
{
if(l<r) push(x);
if(l == r) return setv[x];
int mid = (l+r)>>;
if(qx <= mid) return ask(l(x), l, mid, qx);
else return ask(r(x), mid+, r, qx);
} void change(int x, int l, int r, int ql, int qr, int qv)
{
if(l<r) push(x);
if(ql<=l && r<=qr)
{
setv[x] = qv;
return;
}
int mid=(l+r)>>;
if(ql <= mid) change(l(x),l,mid,ql,qr,qv);
if(mid < qr) change(r(x),mid+,r,ql,qr,qv);
} int dist(int x, int y)
{
if(de[x] < de[y]) swap(x, y);
int ans = ;
for(int i = ;~i;i--)
if(de[fa[x][i]] >= de[y]) ans += dis[x][i], x = fa[x][i];
if(x == y) return ans;
for(int i = ;~i;i--)
if(fa[x][i] != fa[y][i])
{
ans += dis[x][i]; x = fa[x][i];
ans += dis[y][i]; y = fa[y][i];
}
return ans+dis[x][]+dis[y][];
} void dfs1(int x, int tmp)
{
siz[x] = ;
h[x] = ;
for(int i = g[x];i;i = E[i].to)
if(!v[p] && p != tmp)
{
dfs1(p, x);
h[x] = max(h[x], siz[p]);
siz[x] += siz[p];
}
h[x] = max(h[x], lef_now - siz[x]);
if(!hev || h[x] < h[hev]) hev = x;
} void dfs(int x)
{
for(int i = g[x];i;i = E[i].to)
if(p != fa[x][])
{
fa[p][] = x;
dis[p][] = E[i].v;
de[p] = de[x] + ;
dfs(p);
}
} void dfs2(int x, int tmp, int now)
{
nod[now].push_back(MP(d[x], x));
for(int i = g[x];i;i = E[i].to)
if(!v[p] && p != tmp)
{
d[p] = d[x] + E[i].v;
dfs2(p, x, now);
}
} void solve(int x)
{
v[x] = ;
d[x] = ;
dfs2(x, x, x);
sort(nod[x].begin(), nod[x].end());
for(int i = ;i < (int)nod[x].size();i++)
{
id[x].push_back( MP(nod[x][i].second, i) );
hevs[nod[x][i].second].push_back(x);
}
sort(id[x].begin(), id[x].end());
root[x] = build(, nod[x].size()-);
for(int i = g[x];i;i = E[i].to)
if(!v[p])
{
hev = ;
lef_now = siz[p];
dfs1(p, x);
solve(hev);
}
} int find(int x,int len)
{
int l=,r=nod[x].size()-;
while(r-l>)
{
int mid = (l+r)>>;
if(nod[x][mid].first <= len) l=mid;
else r=mid;
}
for(int i=r;i>=l;i--)
if(nod[x][i].first <= len) return i;
return -;
} void com_change(int x, int len, int v)
{
for(int i = ;i < (int)hevs[x].size();i++)
{
int tmp = hevs[x][i];
int t = find(tmp, len - dist(x, tmp));
if(t == -) continue;
change(root[tmp], , id[tmp].size()-, , t, v);
}
} int com_ask(int x)
{
int ans = ;
for(int i = ;i < (int)hevs[x].size();i++)
{
int tmp = hevs[x][i];
int t = (*lower_bound(id[tmp].begin(), id[tmp].end(), MP(x, -))).second;
ans = max(ans, ask(root[tmp], , id[tmp].size()-, t));
}
return col[ans];
} int main()
{
scanf("%d", &n);
for(int i = , x, y, v;i < n;i++)
{
scanf("%d %d %d", &x, &y, &v);
addedge(x, y, v);
addedge(y, x, v);
}
de[]=;
dfs();
for(int j = ;j <= ;j++)
{
for(int i = ;i <= n;i++)
{
fa[i][j] = fa[fa[i][j-]][j-];
dis[i][j] = dis[fa[i][j-]][j-] + dis[i][j-];
}
}
totn = ;
hev = ;
lef_now = n;
dfs1(, );
solve(hev);
scanf("%d", &m);
int x,cmd,len,tot=;
while(m--)
{
scanf("%d%d",&cmd,&x);
if(cmd==)
{
scanf("%d%d",&len,&col[++tot]);
com_change(x,len,tot);
}
else printf("%d\n",com_ask(x));
}
return ;
}
LWDB的更多相关文章
- 【Codeforces】Gym100633 D. LWDB
题解 点分治,然后每个点上挂着一个距离不超过\(a_{i}\)的颜色改成\(c\) 用一个单调栈维护距离单调递减,每次查询在每个包括这个点的分治中心的单调栈上二分,找到修改最靠前的颜色作为这个点的颜色 ...
- XV Open Cup named after E.V. Pankratiev. GP of Tatarstan
A. Survival Route 留坑. B. Dispersed parentheses $f[i][j][k]$表示长度为$i$,未匹配的左括号数为$j$,最多的未匹配左括号数为$k$的方案数. ...
- 转weblogic 10.3新建域
一.安装前准备 1.解决linux中文乱码问题 修改/etc/sysconfig/i18n文件 #LANG="en_US.UTF-8"#SUPPORTED="en_US. ...
- SQL Server优化技巧之SQL Server中的"MapReduce"
日常的OLTP环境中,有时会涉及到一些统计方面的SQL语句,这些语句可能消耗巨大,进而影响整体运行环境,这里我为大家介绍如何利用SQL Server中的”类MapReduce”方式,在特定的统计情形中 ...
- 写给iOS程序员的命令行使用秘籍
http://www.jianshu.com/p/44d3b8f713f2 Mac OS是Unix系统的分支,有着强大的命令行功能.很多事情在命令行下处理会事半功倍,所以我就iOS程序员可能会用到的功 ...
- VxWorks 引导程序
前言:vxworks 的一些文件,如 usrconfig.c 在 config,comp目录中均有出现,因编译方式而选择某一个文件,命令行方式采用 config 目录文件,tornado 图形界面配置 ...
随机推荐
- 验证loadrunner对Ajax内容的校验
前一阵和开发的同事一起測试某个系统的性能.此系统是发送Ajax请求到后台,再调用第三方的某项服务. 第三方服务的性能由不得我们控制.因此开发者做了一下改进.超时则直接返回. 于是在loadrunner ...
- 文件另存为——Autocad.doc.SaveAs
一.前言 使用pyautocad编辑好cad图纸后,往往涉及到一个保存的问题,但是官方文档并未提及,所以只能自己来了,测试了好久,终于是找到了保存的命令和参数说明. 二.方法介绍 Autocad.do ...
- 你必须了解的java内存管理机制(二)-内存分配
前言 在上一篇文章中,我们花了较大的篇幅去介绍了JVM的运行时数据区,并且重点介绍了栈区的结构及作用,相关内容请猛戳!在本文中,我们将主要介绍对象的创建过程及在堆中的分配方式. 相关链接(注:文章讲解 ...
- mysql could not be resolved: Name or service not known
问题: mysql DNS反解:skip-name-resolve 错误日志有类似警告: 1.120119 16:26:04 [Warning] IP address '192.168.1.10' c ...
- Rest Api(转载)
来源:http://www.cnblogs.com/springyangwc/archive/2012/01/18/2325784.html 概述 REST 从资源的角度来观察整个网络,分布在各处的资 ...
- 开源流媒体播放器EasyPlayer
配套开源流媒体服务器EasyDarwin,我们开发了一款开源的流媒体播放器EasyPlayer(现在已经升级合并到开源EasyClient中):同样,EasyPlayer目前只支持RTSP流媒体协议, ...
- mongodb分页
1 什么是mongodb的分页 就是一次返回表中的连续若干行. 2 什么是sql分页 同样是返回表中的连续若干行. 3 如何实现sql分页 利用order by xxx limit xxx 4 如何实 ...
- Machine Learning in Action(2) 决策树算法
决策树也是有监督机器学习方法. 电影<无耻混蛋>里有一幕游戏,在德军小酒馆里有几个人在玩20问题游戏,游戏规则是一个设迷者在纸牌中抽出一个目标(可以是人,也可以是物),而猜谜者可以提问题, ...
- jQuery remove()与jQuery empty()的区别
jQuery remove() 方法删除被选元素及其子元素.举例如下: <!DOCTYPE html> <html> <head> <script src=& ...
- 【Windows核心编程】一个使用内存映射文件进行进程间通信的例子
进程间通信的方式有很多种,其底层原理使用的都是内存映射文件. 本文实现了Windows核心编程第五版475页上的demo,即使用内存映射文件来在进程间通信. 进程1 按钮[Create mappin ...