bzoj2117
动态电分治+二分
肯定要枚举所有点对,那么我们建出点分树降低树高,然后每个点存下点分树中所有子树到这个点的距离,然后二分+lower_bound就行了。
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + ;
namespace IO
{
const int Maxlen = N * ;
char buf[Maxlen], *C = buf;
int Len;
inline void read_in()
{
Len = fread(C, , Maxlen, stdin);
buf[Len] = '\0';
}
inline void fread(int &x)
{
x = ;
int f = ;
while (*C < '' || '' < *C) { if(*C == '-') f = -; ++C; }
while ('' <= *C && *C <= '') x = (x << ) + (x << ) + *C - '', ++C;
x *= f;
}
inline void fread(long long &x)
{
x = ;
long long f = ;
while (*C < '' || '' < *C) { if(*C == '-') f = -; ++C; }
while ('' <= *C && *C <= '') x = (x << ) + (x << ) + *C - '', ++C;
x *= f;
}
inline void read(int &x)
{
x = ;
int f = ; char c = getchar();
while(c < '' || c > '') { if(c == '-') f = -; c = getchar(); }
while(c >= '' && c <= '') { x = (x << ) + (x << ) + c - ''; c = getchar(); }
x *= f;
}
inline void read(long long &x)
{
x = ;
long long f = ; char c = getchar();
while(c < '' || c > '') { if(c == '-') f = -; c = getchar(); }
while(c >= '' && c <= '') { x = (x << 1ll) + (x << 3ll) + c - ''; c = getchar(); }
x *= f;
}
} using namespace IO;
int rd()
{
int x = , f = ; char c = getchar();
while(c < '' || c > '') { if(c == '-') f = -; c = getchar(); }
while(c >= '' && c <= '') { x = x * + c - ''; c = getchar(); }
return x * f;
}
struct edge {
int nxt, to, w;
} e[N << ];
int n, q, cnt = , root, rt, tot, k;
int head[N], size[N], f[N], Fa[N], dep[N], val[N << ], vis[N], Log[N << ], pos[N << ], mn[N << ][], dis[N];
vector<int> ddis[N], DDis[N];
void link(int u, int v, int w)
{
e[++cnt].nxt = head[u];
head[u] = cnt;
e[cnt].to = v;
e[cnt].w = w;
}
void getroot(int u, int last, int S)
{
f[u] = ;
size[u] = ;
for(int i = head[u]; i; i = e[i].nxt) if(!vis[e[i].to] && e[i].to != last)
{
getroot(e[i].to, u, S);
size[u] += size[e[i].to];
f[u] = max(f[u], size[e[i].to]);
}
f[u] = max(f[u], S - size[u]);
if(f[u] < f[root]) root = u;
}
int getsize(int u, int last)
{
int ret = ;
for(int i = head[u]; i; i = e[i].nxt) if(e[i].to != last && !vis[e[i].to])
ret += getsize(e[i].to, u);
return ret;
}
void divide(int u)
{
vis[u] = ;
for(int i = head[u]; i; i = e[i].nxt) if(!vis[e[i].to])
{
root = ;
getroot(e[i].to, u, getsize(e[i].to, u));
Fa[root] = u;
divide(root);
}
}
void dfs(int u, int last)
{
mn[pos[u] = ++tot][] = dis[u];
for(int i = head[u]; i; i = e[i].nxt) if(e[i].to != last)
{
dis[e[i].to] = dis[u] + e[i].w;
dep[e[i].to] = dep[u] + ;
dfs(e[i].to, u);
mn[++tot][] = dis[u];
}
}
int Dis(int u, int v)
{
int ret = dis[u] + dis[v];
if(pos[u] < pos[v]) swap(u, v);
int x = Log[pos[u] - pos[v] + ];
return ret - * min(mn[pos[v]][x], mn[pos[u] - ( << x) + ][x]);
}
int ask(vector<int> &t, int x)
{
return upper_bound(t.begin(), t.end(), x) - t.begin();
}
int check(int u, int x)
{
int ret = ;
for(int i = u; i; i = Fa[i])
{
int d = ask(ddis[i], x - Dis(u, i));
ret += d;
if(ret > * n) return ret;
}
for(int i = Fa[u]; i; i = Fa[i]) if(Dis(u, i) <= x) ++ret;
for(int i = u; Fa[i]; i = Fa[i])
{
int d = ask(DDis[i], x - Dis(u, Fa[i]));
ret -= d;
}
return ret;
}
int query(int u, int k)
{
int l = , r = 1e9 + , ret = ;
while(r - l > )
{
int mid = (l + r) >> ;
int tmp = check(u, mid);
if(check(u, mid) >= k) r = ret = mid;
else l = mid;
}
return ret;
}
int main()
{
char opt[];
scanf("%s", opt);
read(n);
read(k);
for(int i = ; i < n; ++i)
{
int u, v, w;
read(u);
read(v);
read(w);
link(u, v, w);
link(v, u, w);
}
dfs(, );
for(int i = ; i <= tot; ++i) Log[i] = Log[i >> ] + ;
for(int j = ; j <= ; ++j)
for(int i = ; i + ( << j) - <= tot; ++i)
mn[i][j] = min(mn[i][j - ], mn[i + ( << (j - ))][j - ]);
f[] = 1e9;
getroot(, , getsize(, ));
rt = root;
divide(root);
for(int i = ; i <= n; ++i)
{
for(int j = Fa[i]; j; j = Fa[j]) ddis[j].push_back(Dis(i, j));
for(int j = i; Fa[j]; j = Fa[j]) DDis[j].push_back(Dis(i, Fa[j]));
}
for(int i = ; i <= n; ++i)
{
sort(ddis[i].begin(), ddis[i].end());
sort(DDis[i].begin(), DDis[i].end());
}
for(int i = ; i <= n; ++i) printf("%d\n", query(i, k));
return ;
}
bzoj2117的更多相关文章
- 【BZOJ2117】 [2010国家集训队]Crash的旅游计划
[BZOJ2117] [2010国家集训队]Crash的旅游计划 Description 眼看着假期就要到了,Crash由于长期切题而感到无聊了,因此他决定利用这个假期和好友陶陶一起出去旅游. Cra ...
- BZOJ4317Atm的树&BZOJ2051A Problem For Fun&BZOJ2117[2010国家集训队]Crash的旅游计划——二分答案+动态点分治(点分树套线段树/点分树+vector)
题目描述 Atm有一段时间在虐qtree的题目,于是,他满脑子都是tree,tree,tree…… 于是,一天晚上他梦到自己被关在了一个有根树中,每条路径都有边权,一个神秘的声音告诉他,每个点到其他的 ...
- [BZOJ2051]A Problem For Fun/[BZOJ2117]Crash的旅游计划/[BZOJ4317]Atm的树
[BZOJ2051]A Problem For Fun/[BZOJ2117]Crash的旅游计划/[BZOJ4317]Atm的树 题目大意: 给出一个\(n(n\le10^5)\)个结点的树,每条边有 ...
- BZOJ2117: [2010国家集训队]Crash的旅游计划
裸点分,点分树每层维护有序表,查询二分,复杂度$O(nlog^3n)$. #include<bits/stdc++.h> #define M (u+v>>1) #define ...
- [BZOJ2117]Crash的旅游计划
Description 眼看着假期就要到了,Crash由于长期切题而感到无聊了,因此他决定利用这个假期和好友陶陶一起出去旅游. Crash和陶陶所要去的城市里有N (N > 1) 个景点,Cra ...
随机推荐
- yarn 基本用法
1.初始化一个新的项目 yarn init 2.添加一个依赖包 yarn add [package] yarn add [package]@[version] yarn add [package]@[ ...
- Twitter网站架构分析介绍
http://www.kaiyuanba.cn/html/1/131/147/7539.htm作为140个字的缔造者,twitter太简单了,又太复杂了,简单是因为仅仅用140个字居然使有几次世界性事 ...
- Python+Selenium框架unittest执行脚本方法之discover()方法
继续接着介绍,如何利用unittest管理和执行测试用例的问题,这里我们还是利用之前已经有的三条测试用例,如果你跳过了前面文章,请回到框架设计篇的第八篇和第七篇,里面有相关测试类的文件.本文来介绍,如 ...
- Codeforces 569 B. Inventory
click here~~ **B. Inventory** time limit per test1 second memory limit per test256 megabytes inputst ...
- mdadm
http://en.wikipedia.org/wiki/Mdadm mdadm From Wikipedia, the free encyclopedia mdadm Original au ...
- IMDB-WIKI - 具有年龄和性别标签的500k +脸部图像
Rasmus Rothe, Radu Timofte, Luc Van Gool DEX:从单一形象深刻地看待年龄 观看 人物研讨会国际计算机视觉大会(ICCV),2015*获胜LAP面对年龄估计的挑 ...
- Canvas学习笔记——拖曳与投掷物体
首先用一个例子来演示这个效果: 鼠标可以拖曳和投掷小球 // > 16 & 0xff, g = color >> 8 & 0xff, b = color > ...
- Netty 100万级高并发服务器配置
前言 每一种该语言在某些极限情况下的表现一般都不太一样,那么我常用的Java语言,在达到100万个并发连接情况下,会怎么样呢,有些好奇,更有些期盼. 这次使用经常使用的顺手的netty NIO框架(n ...
- SpringMVC+Spring+MyBatis配置
今天配置项目时遇到一个问题,tomcat启动没有报错,但是访问页面的时总是报404,后台打印的日志是: 8080-exec-1] WARN springframework.web.servlet.Pa ...
- HDU4850 Wow! Such String! —— 字符串构造
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4850 代码如下: #include <iostream> #include <cst ...