题目大意及题解
cf教会我c++11
我的代码:
#include<algorithm>
#include<ctype.h>
#include<cstdio>
#include<vector>
#include<set>
#define int long long
#define INF 2147483647
#define pll pair<long long,long long>
#define mp make_pair
#define pb push_back
#define sd signed
#define fs first
#define sn second
#define N 100020
using namespace std;
inline int read(){
int x=0,f=1;char c;
do c=getchar(),f=c=='-'?-1:f; while(!isdigit(c));
do x=(x<<3)+(x<<1)+c-'0',c=getchar(); while(isdigit(c));
return x*f;
}
typedef long long LL;
int n,m,x,y,tk,tb,top;
int fir[N],siz[N];
bool b[N];
vector<pll> v;
struct Edge{
int to,nex,k,b;
Edge(){}
Edge(int to,int nex,int k,int b):to(to),nex(nex),k(k),b(b){}
}nex[N<<1];
inline void add(int x,int y,int k,int b){
nex[++top]=Edge(y,fir[x],k,b);
fir[x]=top;
}
void GetSize(int x,int fa){
siz[x]=1;
for(int i=fir[x];i;i=nex[i].nex){
if(nex[i].to==fa || b[nex[i].to]) continue;
GetSize(nex[i].to,x);
siz[x]+=siz[nex[i].to];
}
}
int GetRoot(int x,int fa,int sum){
int tmp=0;
for(int i=fir[x];i;i=nex[i].nex){
if(b[nex[i].to] || nex[i].to==fa) continue;
if(siz[nex[i].to]>siz[tmp]) tmp=nex[i].to;
}
return (siz[tmp]>sum/2)?GetRoot(tmp,x,sum):x;
}
struct Line{
mutable LL k,b,p;
Line(){}
Line(LL k,LL b,LL p):k(k),b(b),p(p){}
bool operator < (const Line &a) const{
return k<a.k;
}
};
struct Data : multiset<Line>{
inline bool check(iterator x,iterator y){
if(y==end()){
x->p=INF;
return 0;
}
if(x->k==y->k) x->p=(x->b>y->b?INF:-INF);
else x->p=(y->b-x->b)/(x->k-y->k)-(((y->b-x->b)^(x->k-y->k))<0)*(((y->b-x->b)%(x->k-y->k))!=0);
return x->p>=y->p;
}
inline void add(LL k,LL b){
auto t=insert(Line(k,b,0));
auto nex=t;
++nex;
while(check(t,nex)) nex=erase(nex);
auto x=t;
if(x!=begin() && check(--x,t)){
t=erase(t);
check(x,t);
}
t=x;
while(t!=begin() && (--x)->p>=t->p){
t=erase(t);
check(x,t);
t=x;
}
}
}tmp,ans;
struct pp{
int k,b,p;
pp(){}
pp(int k,int b,int p):k(k),b(b),p(p){}
}a[N];
void GetRoute(int x,int fa,LL sumk,LL sumb){
bool t=false;
for(int i=fir[x];i;i=nex[i].nex){
if(nex[i].to==fa || b[nex[i].to]) continue;
t=true;
GetRoute(nex[i].to,x,sumk+nex[i].k,sumb+nex[i].b);
}
if(!t) tmp.add(sumk,sumb);
}
inline void update(Data a,Data b){
static vector<pll>q1,q2;
q1.clear();q2.clear();
for(auto it:a){
if(!q1.empty() && it.k==q1[q1.size()-1].fs){
q1[q1.size()-1].sn=max(q1[q1.size()-1].sn,it.b);
continue;
}
q1.pb(mp(it.k,it.b));
}
for(auto it:b){
if(!q2.empty() && it.k==q2[q2.size()-1].fs){
q2[q2.size()-1].sn=max(q2[q2.size()-1].sn,it.b);
continue;
}
q2.pb(mp(it.k,it.b));
}
static int l,r;
l=r=0;
while(l<(sd)q1.size() && r<(sd)q2.size()){
v.pb(mp(q1[l].fs+q2[r].fs,q1[l].sn+q2[r].sn));
if(l+1==(sd)q1.size()) r++;
else if(r+1==(sd)q2.size()) l++;
else{
double p1=-(double)(q1[l+1].sn-q1[l].sn)/(double)(q1[l+1].fs-q1[l].fs);
double p2=-(double)(q2[r+1].sn-q2[r].sn)/(double)(q2[r+1].fs-q2[r].fs);
if(p1<p2) l++;
else r++;
}
}
}
Data Merge(int x,int y,vector<Data> &q){
if(x==y){
Data tmp;
tmp.add(0,0);
update(tmp,q[x]);
return q[x];
}
else{
int mid=(x+y)>>1;
Data t1=Merge(x,mid,q);
Data t2=Merge(mid+1,y,q);
update(t1,t2);
for(auto it:t1)
t2.add(it.k,it.b);
return t2;
}
}
void solve(int x){
b[x]=true;
vector<Data>q;
for(int i=fir[x];i;i=nex[i].nex){
if(b[nex[i].to]) continue;
tmp.clear();
tmp.add(0,0);
GetRoute(nex[i].to,x,nex[i].k,nex[i].b);
q.push_back(tmp);
}
if(!q.empty()) Merge(0,q.size()-1,q);
for(int i=fir[x];i;i=nex[i].nex){
if(b[nex[i].to]) continue;
GetSize(nex[i].to,0);
solve(GetRoot(nex[i].to,x,siz[nex[i].to]));
}
}
main(){
n=read();m=read();
for(int i=1;i<n;i++){
x=read();y=read();tk=read();tb=read();
add(x,y,tk,tb);add(y,x,tk,tb);
}
GetSize(1,0);
solve(GetRoot(1,0,siz[1]));
ans.add(0,0);
for(auto it:v) ans.add(it.fs,it.sn);
top=0;
for(auto it:ans) a[++top]=pp(it.k,it.b,it.p);
for(int i=0,j=1;i<m;i++){
while(a[j].p<i) j++;
printf("%lld ",a[j].k*i+a[j].b);
}
return 0;
}