# 【BZOJ-3784】树上的路径 点分治 + ST + 堆

## 3784: 树上的路径

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 462  Solved: 153
[Submit][Status][Discuss]

5 10
1 2 1
1 3 2
2 4 3
2 5 4

7
7
6
5
4
4
3
3
2
1

## HINT

N<=50000,M<=Min(300000,n*(n-1) /2

## Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define MAXN 100010
#define MAXM 1000100
int N,M;
struct EdgeNode{int next,to,val;}edge[MAXN<<1];
int maxx[MAXN],size[MAXN],Sz,root,L[MAXM],R[MAXM],D[MAXM],pl,pr,dfn;
bool visit[MAXN];
void DFSRoot(int now,int last)
{
size[now]=1; maxx[now]=0;
if (edge[i].to!=last && !visit[edge[i].to])
{
DFSRoot(edge[i].to,now);
size[now]+=size[edge[i].to];
maxx[now]=max(maxx[now],size[edge[i].to]);
}
maxx[now]=max(maxx[now],Sz-size[now]);
if (maxx[now]<maxx[root]) root=now;
}
void Get(int x,int last,int Dis)
{
D[++dfn]=Dis; L[dfn]=pl,R[dfn]=pr;
if (!visit[edge[i].to] && edge[i].to!=last)
Get(edge[i].to,x,Dis+edge[i].val);
}
void Divide(int x)
{
visit[x]=1;
pl=pr=++dfn;
if (!visit[edge[i].to]) Get(edge[i].to,x,edge[i].val),pr=dfn;
if (!visit[edge[i].to])
{
Sz=size[edge[i].to]; root=0;
DFSRoot(edge[i].to,x);
Divide(root);
}
}
int log2[MAXM],dp[20][MAXM];
int Max(int x,int y) {return D[x]>D[y]? x:y;}
void ST()
{
log2[0]=-1;
for (int i=1; i<=N; i++)
if (i&(i-1)) log2[i]=log2[i-1]; else log2[i]=log2[i-1]+1;
for (int i=1; i<=dfn; i++) dp[0][i]=i;
for (int j=1; (1<<j)<=dfn; j++)
for (int i=1; i+(1<<j)-1<=dfn; i++)
dp[j][i]=Max(dp[j-1][i],dp[j-1][i+(1<<j-1)]);
}
inline int RMQ(int l,int r)
{
int tmp=log2[r-l+1];
return Max(dp[tmp][l],dp[tmp][r-(1<<tmp)+1]);
}
struct HeapNode
{
int ip,L,R,pos;
HeapNode (int ip=0,int L=0,int R=0,int pos=0)
: ip(ip),L(L),R(R),pos(pos) {}
bool operator < (const HeapNode & A) const
{return D[ip]+D[pos]<D[A.ip]+D[A.pos];}
};
priority_queue<HeapNode>heap;
int main()
{
maxx[root=0]=Sz=N;
DFSRoot(1,0);
Divide(root);
ST();
for (int i=1; i<=dfn; i++)
heap.push( HeapNode(i,L[i],R[i],RMQ(L[i],R[i])) );
while (M--)
{
HeapNode now=heap.top(); heap.pop();
printf("%d\n",D[now.ip]+D[now.pos]);
HeapNode ls=now; ls.R=now.pos-1;
if (ls.R>=ls.L) ls.pos=RMQ(ls.L,ls.R),heap.push(ls);
HeapNode rs=now; rs.L=now.pos+1;
if (rs.R>=rs.L) rs.pos=RMQ(rs.L,rs.R),heap.push(rs);
}
return 0;
}

——It's a lonely path. Don't make it any lonelier than it has to be.
posted @ 2016-08-20 09:04  DaD3zZ  阅读(233)  评论(0编辑  收藏  举报