BZOJ 1468 Tree
点分治
考虑统计过含重心的合法路径数
扫一下,sort,双指针
复杂度我也不清楚
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN=41111;
int N;
long long K;
struct Vert{
int FE;
int Size, Val;
bool Vis;
long long Dis;
} V[MAXN];
struct Edge{
int x, y, next;
long long l;
} E[MAXN<<1];
int Ecnt=0;
void addE(int a, int b, long long c){
++Ecnt;
E[Ecnt].x=a;E[Ecnt].y=b;E[Ecnt].l=c;
E[Ecnt].next=V[a].FE;V[a].FE=Ecnt;
}
void getSize(int at, int f=0){
V[at].Size=1;
for(int k=V[at].FE, to;k>0;k=E[k].next){
to=E[k].y;
if(to==f || V[to].Vis) continue;
getSize(to, at);
V[at].Size+=V[to].Size;
}
}
int AllSize;
void getVal(int at, int f=0){
V[at].Val=AllSize-V[at].Size;
for(int k=V[at].FE, to;k>0;k=E[k].next){
to=E[k].y;
if(to==f || V[to].Vis) continue;
getVal(to, at);
V[at].Val=max(V[at].Val, V[to].Size);
}
}
int getG(int at, int f=0){
int ret=at;
for(int k=V[at].FE, to;k>0;k=E[k].next){
to=E[k].y;
if(to==f || V[to].Vis) continue;
to=getG(to, at);
if(V[ret].Val>V[to].Val) ret=to;
}
return ret;
}
void getD(int at, int f=0){
for(int k=V[at].FE, to;k>0;k=E[k].next){
to=E[k].y;
if(to==f || V[to].Vis) continue;
V[to].Dis=V[at].Dis+E[k].l;
getD(to, at);
}
}
int ANS=0;
long long Tot[MAXN], Top;
long long Now[MAXN], Nop;
void getN(int at, int f=0){
for(int k=V[at].FE, to;k>0;k=E[k].next){
to=E[k].y;
if(to==f || V[to].Vis) continue;
getN(to, at);
}
Now[++Nop]=V[at].Dis;
}
void Div(int at){
getSize(at);AllSize=V[at].Size;
getVal(at);at=getG(at);
V[at].Vis=true;
V[at].Dis=0LL;
getD(at);
Top=0;
Tot[++Top]=V[at].Dis;
for(int k=V[at].FE, to;k>0;k=E[k].next){
to=E[k].y;
if(V[to].Vis) continue;
Nop=0;
getN(to, at);
sort(Now+1, Now+Nop+1);
for(int i=1, j=Top;i<=Nop;++i){
while(j>0 && Tot[j]+Now[i]>K) --j;
ANS+=j;
}
for(int i=1;i<=Nop;++i)
Tot[++Top]=Now[i];
sort(Tot+1, Tot+Top+1);
}
for(int k=V[at].FE, to;k>0;k=E[k].next){
to=E[k].y;
if(V[to].Vis) continue;
Div(to);
}
}
int main(){
ios_base::sync_with_stdio(false);
cin >> N;
for(int i=1, a, b;i<N;++i){
cin >> a >> b >> K;
addE(a, b, K);addE(b, a, K);
}
cin >> K;
Div(1);
cout << ANS << endl;
return 0;
}
/*
7
1 6 13
6 3 9
3 5 7
4 1 3
2 4 20
4 7 2
10
5
*/