3672: [Noi2014] Buy Tickets tree split + segment tree + slope optimization

Source: Internet
Author: User
Tags min ticket
Description

This summer, NOI in Sz City ushered in her 30-year-old birthday. Oier from N cities all over the country will go to SZ City to participate in this event.
The cities of the country constituted a tree with SZ as root, each city with its father connected with the road. For the sake of convenience, we numbered n cities across the country with integers from 1 to n. The number of SZ city is 1. For any city other than SZ, we gave it the Father City FV on this tree as well as the length SV to the Father City Road.
The approach to SZ city from City v is: Select an ancestor a of City V, pay the fare for the ticket, and take the transportation to a. Then select an ancestor B of City A, pay the fee and arrive at B. And so on until we reach SZ City.
For any city V, we will give a distance limit LV for a vehicle. For the ancestor a of City V, only if the total length of all roads between them does not exceed LV, the City v can only be reached by one purchase ticket to city A, otherwise it cannot be reached by one purchase. For each city V, we also give two non-negative integer PV,QV as the fare parameter. If City v to city A has a total length of D for all roads, then the fare purchased from City v to city A is dpv+qv.
Each city's oier want to arrive at Sz City, the total amount of money used to buy tickets. Your task is to tell the oier of each city how much money they have spent at least. Input

The 1th line contains 2 nonnegative integer n,t that represent the number of cities and the data type (meaning will be mentioned later). Enter the 2nd to n rows of the file, each describing a city other than Sz. Where the V line contains 5 non-negative integer f_v,s_v,p_v,q_v,l_v, which represents the City V's father City, it is limited to the length of the Father City Road, the fare of two parameters and the distance. Please note: The input does not include the SZ city numbered 1, the 2nd row to the nth row describes the City 2 to the city N respectively. Output

The output contains n-1 rows with one integer per line. The line v indicates the minimum purchase fee from the city v+1 to Sz City. Also note that the output does not contain a SZ city numbered 1. Sample Input

7 3

1 2 20) 0 3

1 5 10) 100 5

2 4 10) 10 10

2 9 1) 100 10

3 5 20) 100 10

4 4 0 Sample Output

40

150

70

149

300

About

It is said that this problem has nlog^2 practice, but I am too food, obediently to write nlog^3, we first tree, for each point we find out which point it can come from the top, and then extract the Logn chain, in the segment tree each node to maintain a convex packet, Then find each chain corresponding to the Logn interval, respectively, in the convex hull two points for the best advantage, take the minimum value.

#include <cstdio> #include <cstdlib> #include <iostream> #include <ctime> #include <cmath > #include <cstring> #include <string> #include <algorithm> #include <iomanip> #include <
Vector> using namespace std;
#define INF 1e100 int siz[400000];
int son[400000];
int fa[400000][18];
Long Long deep[400000];
int f[400000];
int dfsx[400000];
int wz[400000];
    struct Bian {int l,r;
Long Long V;
}A[400100];
int fir[400010];
int nex[400010];
int top[400010];
int tot=1;
    void Add_edge (int l,int R,long long v) {a[++tot].l=l;
    A[tot].r=r;
    A[tot].v=v;
    NEX[TOT]=FIR[L];
Fir[l]=tot;
    } void dfs1 (int u,int fro) {Fa[u][0]=fro;
    Siz[u]=1;
    son[u]=0;
        for (int o=fir[u];o;o=nex[o]) {deep[a[o].r]=deep[u]+a[o].v;
        DFS1 (A[o].r,u);
        if (Siz[a[o].r]>siz[son[u]]) SON[U]=A[O].R;
    SIZ[U]+=SIZ[A[O].R];
}} int id=0;
    void dfs2 (int u,int fro) {dfsx[++id]=u;
    Wz[u]=id; if (u==son[fa[U][0]]) top[u]=top[fa[u][0];
    else Top[u]=u;
    if (Son[u]) DFS2 (son[u],u);
        for (int o=fir[u];o;o=nex[o]) {if (A[o].r==son[u]) continue;
    DFS2 (A[o].r,u);
    }} struct Point {Long long x, y; Point () {} ' point (long _,long long __): X (_), Y (__) {} long double operator * (point B) {if (x==b.x) r Eturn y<b.y?
        Inf:-inf;
        a long double yy=y-b.y;
        a long double xx=x-b.x;
    return yy/xx;
}
};
    void Insert (vector<point> &v,point p) {int siz=v.size ();
    if (siz>=1 && v[siz-1].x>p.x) return;
    while (siz>1 && v[siz-2]*v[siz-1]>v[siz-1]*p) siz--, v.pop_back ();
V.push_back (P);
        } namespace Seg {struct Xianduan {int l,r;
    Vector<point> Hull;
    }A[530000];
        void Make_tree (int o,int l,int r) {a[o].l=l;
        A[o].r=r;
        if (l==r) return;
        int mid=l+r>>1;
        Make_tree (2*o,l,mid); Make_tree (2*o+1,mid+1,R);
        } point Get_minn (int o,long long p) {int siz=a[o].hull.size ();
        if (siz==0) return point ( -2147483647,-1);
        if (siz==1) return a[o].hull[0];
        if (P<a[o].hull[0]*a[o].hull[1]) return a[o].hull[0];
        if (P>a[o].hull[siz-2]*a[o].hull[siz-1]) return a[o].hull[siz-1];
        int l=1,r=siz-2;
        int jilu=1;
            while (l<=r) {int mid=l+r>>1;
            if (a[o].hull[mid-1]*a[o].hull[mid]<p) jilu=mid,l=mid+1;
        else r=mid-1;
        } point Mid=a[o].hull[jilu];
    return mid; } Long long Get_minn (int o,int l,int R,long long p) {if (A[o].r<l | | a[o].l>r) return (long Long) 1e1
        8;
            if (a[o].l>=l && a[o].r<=r) {point Mid=get_minn (o,p);
            if (mid.x==-2147483647) return 1e18;
        return mid.y-mid.x*p;
    } return min (Get_minn (2*o,l,r,p), Get_minn (2*o+1,l,r,p)); } void Insert (int o,iNT Wz,point p) {if (A[o].r<wz | | a[o].l>wz) return;
        Insert (A[O].HULL,P);
        if (A[O].L==A[O].R) return;
        Insert (2*O,WZ,P);
    Insert (2*O+1,WZ,P);
    }} Long long Get_maxx (int x,int y,long long p) {Long long re=1e18;
        while (Top[x]!=top[y]) {if (deep[top[x]]<deep[top[y])) swap (x, y);
        Re=min (Re,seg::get_minn (1,wz[top[x]],wz[x],p));
    X=FA[TOP[X]][0];
    } if (Deep[x]<deep[y]) swap (x, y);
    Re=min (Re,seg::get_minn (1,wz[y],wz[x],p));
return re;
} int n,m;
Long Long p[400000];
Long Long q[400000];
Long Long l[400000];
    void Init () {scanf ("%d%d", &n,&m);
        for (int i=2;i<=n;i++) {long long ll,v;
        scanf ("%lld%lld%lld%lld%lld", &ll,&v,&p[i],&q[i],&l[i]);
    Add_edge (LL,I,V);
    } DFS1 (1,0);
    DFS2 (1,0);
    for (int. i=1;i<=n;i++) for (int j=1;j<=17;j++) fa[i][j]=fa[fa[i][j-1]][j-1];
Seg::make_tree (1,1,n); } bool Flag=false;
Long Long anss[400000];
    void Dfs (int u) {if (u==1) Seg::insert (1,wz[1],point (0,0));
        else {int x=u;
        for (int i=17;i>=0;i--) if (Fa[x][i] && deep[fa[x][i]]+l[u]>=deep[u]) x=fa[x][i];
        Long Long Ans=get_maxx (X,fa[u][0],p[u]) +deep[u]*p[u]+q[u];
        Seg::insert (1,wz[u],point (Deep[u],ans));
    Anss[u]=ans;
} for (int o=fir[u];o;o=nex[o]) DFS (A[O].R);
    } int main () {init ();
    DFS (1);
    printf ("%lld\n", anss[2]);
    for (int i=3;i<=n;i++) printf ("%lld\n", Anss[i]);
return 0;
 }

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.