BZOJ2051 : A Problem For Fun

树的点分治,将点分治的过程记录下来,每一个分治结构按到分治中心的距离维护所有点。

对于一个点二分答案,然后在$O(\log n)$个分治结构中二分查找,时间复杂度$O(n\log^3n)$。

#include<cstdio>
#include<algorithm>
const int N=50010,M=1000010;
int n,m,i,x,y,z,g[N],nxt[N<<1],v[N<<1],w[N<<1],ok[N<<1],ed=1;
int son[N],f[N],size,now,cnt;
int G[N],NXT[M],V[2][M],W[M],ED,rl[N],rr[N],el[M],er[M],q[M<<1],tot;
inline void add(int x,int y,int z){v[++ed]=y,w[ed]=z,nxt[ed]=g[x],ok[ed]=1,g[x]=ed;}
inline void ADD(int x,int y,int z,int w){V[0][++ED]=y;V[1][ED]=z;W[ED]=w;NXT[ED]=G[x];G[x]=ED;}
void findroot(int x,int pre){
  son[x]=1;f[x]=0;
  for(int i=g[x];i;i=nxt[i])if(ok[i]&&v[i]!=pre){
    findroot(v[i],x);
    son[x]+=son[v[i]];
    if(son[v[i]]>f[x])f[x]=son[v[i]];
  }
  if(size-son[x]>f[x])f[x]=size-son[x];
  if(f[x]<f[now])now=x;
}
void dfs(int x,int pre,int dis){
  q[++tot]=dis;
  for(int i=g[x];i;i=nxt[i])if(ok[i]&&v[i]!=pre)dfs(v[i],x,dis+w[i]);
}
void dfs2(int x,int pre,int dis){
  ADD(x,now,cnt,dis);
  q[++tot]=dis;
  for(int i=g[x];i;i=nxt[i])if(ok[i]&&v[i]!=pre)dfs2(v[i],x,dis+w[i]);
}
void solve(int x){
  int i;
  q[rl[x]=++tot]=0;
  for(i=g[x];i;i=nxt[i])if(ok[i])dfs(v[i],x,w[i]);
  std::sort(q+rl[x],q+tot+1);
  rr[x]=tot;
  for(i=g[x];i;i=nxt[i])if(ok[i]){
    el[++cnt]=tot+1;
    dfs2(v[i],x,w[i]);
    std::sort(q+el[cnt],q+tot+1);
    er[cnt]=tot;
  }
  for(i=g[x];i;i=nxt[i])if(ok[i])ok[i^1]=0,f[0]=size=son[v[i]],findroot(v[i],now=0),solve(now);
}
inline int ask(int L,int r,int x){
  int l=L,t=l-1,mid;
  while(l<=r)if(q[mid=(l+r)>>1]<=x)l=(t=mid)+1;else r=mid-1;
  return t-L+1;
}
inline int query(int x,int k){
  int t=ask(rl[x],rr[x],k)-1;
  for(int i=G[x];i;i=NXT[i])t+=ask(rl[V[0][i]],rr[V[0][i]],k-W[i])-ask(el[V[1][i]],er[V[1][i]],k-W[i]);
  return t;
}
inline int getans(int x){
  int l=1,r=10000*(n-1),mid;
  while(l<r)if(query(x,mid=(l+r)>>1)<m)l=mid+1;else r=mid;
  return l;
}
int main(){
  scanf("%d%d",&n,&m);
  for(i=1;i<n;i++)scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z);
  f[0]=size=n;findroot(1,now=0);solve(now);
  for(i=1;i<=n;i++)printf("%d\n",getans(i));
  return 0;
}

  

时间: 2024-11-08 05:17:42

BZOJ2051 : A Problem For Fun的相关文章

bzoj-2051 A Problem For Fun

题意: 给出一棵n个结点的树,边上有权值: 对于每个点求离它第k小的距离: n<=50000: 题解: 正解似乎是树分治维护距离,然后二分答案啥的,时间复杂度O(nlog^3): 但是如果想不到树分治怎么办呢?那么就来写一个逗比做法吧! 考虑从一个点转移到另外一个点,这个转移过程对于一些点是增加这条边的权值,另一些是减少这条边的权值: 而投影到DFS序上,就是对于子树区间的加减修改: 从而将原题转化成区间修改+全局K小值的问题... 呵呵 于是我去膜了膜wyfcyx大爷,得到了一个污算法.. 反

A Math Problem

A Math Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 237    Accepted Submission(s): 117 Problem Description You are given a positive integer n, please count how many positive integers

Water Problem

water problem 发布时间: 2015年10月10日 15:34   时间限制: 1000ms   内存限制: 256M 描述 题意很简单 给你N个数, Q个查询 每次查询给你一个区间[L, R] 你要找出 [L, R] 这个区间里面取模M后的最大值. 输入 第一行一个T,表示测试数据组数.第二行两个整数N, M (1<=N<=10^5, 1<=M<=10^9).第三行给你N个整数 整数范围在1到10^9之间.第四行给你一个整数Q. ( 1<=Q<=10^5)

FOJ Problem 2261 浪里个浪

                                                                                                                                                           Problem 2261 浪里个浪 Accept: 40    Submit: 106Time Limit: 1500 mSec    Memory Limit : 32768 KB Pro

XJTUOJ wmq的A&#215;B Problem FFT

wmq的A×B Problem 发布时间: 2017年4月9日 17:06   最后更新: 2017年4月9日 17:07   时间限制: 3000ms   内存限制: 512M 描述 这是一个非常简单的问题. wmq如今开始学习乘法了!他为了训练自己的乘法计算能力,写出了n个整数,并且对每两个数a,b都求出了它们的乘积a×b.现在他想知道,在求出的n(n−1)2个乘积中,除以给定的质数m余数为k(0≤k<m)的有多少个. 输入 第一行为测试数据的组数. 对于每组测试数据,第一行为2个正整数n,

hidden node and exposed node problem

Exposed node problem In wireless networks, theexposed node problem occurs when a node is prevented from sending packets to other nodes because of a neighboring transmitter. Consider an example of 4 nodes labeled R1, S1, S2, and R2, where the two rece

南阳524 A-B Problem

A-B Problem 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 A+B问题早已经被大家所熟知了,是不是很无聊呢?现在大家来做一下A-B吧. 现在有两个实数A和B,聪明的你,能不能判断出A-B的值是否等于0呢? 输入 有多组测试数据.每组数据包括两行,分别代表A和B. 它们的位数小于100,且每个数字前中可能包含+,- 号. 每个数字前面和后面都可能有多余的0. 每组测试数据后有一空行. 输出 对于每组数据,输出一行. 如果A-B=0,输出YES,否则输出NO

Lab 1: Write a java program for the triangle problem and test the program with Junit.

Tasks: 1. Install Junit(4.12), Hamcrest(1.3) with Eclipse 将两个jar包添加到工程中 2. Install Eclemma with Eclipse 3. Write a java program for the triangle problem and test the program with Junit. [Description of triangle problem]Function triangle takes three i

HDU 1016 Prime Ring Problem(DFS)

题目链接 Problem Description A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ..., n into each circle separately, and the sum of numbers in two adjacent circles should be a prime. Note: the number of first circle should always