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 ...
随机推荐
- Cts框架解析(15)-任务运行完
case运行完成后.会回到CtsTest的run方法中: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXRmb290YmFsbA==/font/5a6L ...
- 笔记03 wpf 在MVVM模式下怎样在Viewmodel里面获得view的控件对象
转自http://blog.csdn.net/qing2005/article/details/6601199http://blog.csdn.net/qing2005/article/detail ...
- cygwin配置个人环境,android模拟器root映象和Babun
零.Windows命令行个人设置 @echo off :: Temporary system path at cmd startup ::set PATH=%PATH%;"C:\Progra ...
- class中的私有属性的访问
在类中的私有属性设置: class Name(): __init__(self): self.__name = 'arnol'` 如何查看: 1,在类中定义一个方法: def getname(self ...
- C++ 坑人系列(1): 让面试官晕倒的题目
今天和几位同仁一起探讨了一下C++的一些基础知识,在座的同仁都是行家了,有的多次当过C++技术面试官.不过我出的题过于刁钻: 不是看起来太难,而是看起来极其容易,但是其实非常难! 结果一圈下来,3道 ...
- 开源流媒体播放器EasyPlayer
配套开源流媒体服务器EasyDarwin,我们开发了一款开源的流媒体播放器EasyPlayer(现在已经升级合并到开源EasyClient中):同样,EasyPlayer目前只支持RTSP流媒体协议, ...
- 针对Web.config敏感信息加密
cd C:\Windows\Microsoft.NET\Framework\v4.0.30319 ==在appSettings节点上添加== <configProtectedData> & ...
- r squared
multiple r squared adjusted r squared http://web.maths.unsw.edu.au/~adelle/Garvan/Assays/GoodnessOfF ...
- windows IDA 调试SO
还是参考了网上的很多资料,感谢这些前辈的分享. ===================================================================== 环境:win ...
- DuiLib笔记之设置文本字体
设置文本字体要用到Font 它的常用属性如下 id 用于标识Font,类型:INT name 用于指定字体名称,类型:STRING size 用于指定字体大小,类型:INT bold 用于指定是否加粗 ...