zoukankan      html  css  js  c++  java
  • Codeforces Round #503 (by SIS, Div. 1)E. Raining season

    题意:给一棵树每条边有a,b两个值,给你一个m,表示从0到m-1,假设当前为i,那么每条边的权值是a*i+b,求该树任意两点的最大权值
    题解:首先我们需要维护出(a,b)的凸壳,对于每个i在上面三分即可,点对用树分治维护,假设当前重心是u,那么把u的直接儿子挨个合并凸壳,这一过程用闵可夫斯基和维护,set启发式合并.

    //#pragma GCC optimize(2)
    //#pragma GCC optimize(3)
    //#pragma GCC optimize(4)
    //#pragma GCC optimize("unroll-loops")
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define db double
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define ld long double
    //#define C 0.5772156649
    //#define ls l,m,rt<<1
    //#define rs m+1,r,rt<<1|1
    #define pll pair<ll,ll>
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define ull unsigned long long
    //#define base 1000000000000000000
    #define fin freopen("a.txt","r",stdin)
    #define fout freopen("a.txt","w",stdout)
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
    inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
    template<typename T>inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
    template<typename T>inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
    inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
    inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;}
    
    using namespace std;
    
    const ull ba=233;
    const db eps=1e-5;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int N=100000+10,maxn=100000+10,inf=0x3f3f3f3f;
    
    struct FastIO {
        static const int S = 1e7;
        int wpos;
        char wbuf[S];
        FastIO() : wpos(0) {}
        inline int xchar() {
            static char buf[S];
            static int len = 0, pos = 0;
            if (pos == len)
                pos = 0, len = fread(buf, 1, S, stdin);
            if (pos == len) exit(0);
            return buf[pos++];
        }
        inline int xuint() {
            int c = xchar(), x = 0;
            while (c <= 32) c = xchar();
            for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
            return x;
        }
        inline int xint()
        {
            int s = 1, c = xchar(), x = 0;
            while (c <= 32) c = xchar();
            if (c == '-') s = -1, c = xchar();
            for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
            return x * s;
        }
        inline void xstring(char *s)
        {
            int c = xchar();
            while (c <= 32) c = xchar();
            for (; c > 32; c = xchar()) * s++ = c;
            *s = 0;
        }
        inline void wchar(int x)
        {
            if (wpos == S) fwrite(wbuf, 1, S, stdout), wpos = 0;
            wbuf[wpos++] = x;
        }
        inline void wint(ll x)
        {
            if (x < 0) wchar('-'), x = -x;
            char s[24];
            int n = 0;
            while (x || !n) s[n++] = '0' + x % 10, x /= 10;
            while (n--) wchar(s[n]);
            wchar('
    ');
        }
        inline void wstring(const char *s)
        {
            while (*s) wchar(*s++);
        }
        ~FastIO()
        {
            if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;
        }
    } io;
    struct edge{int to,Next,a,b;}e[maxn<<1];
    int cnt,head[N],sz[N],zx[N],n;
    pll dis[N];
    bool vis[N];
    void init(){cnt=0;memset(head,-1,sizeof head);memset(vis,0,sizeof vis);}
    void add(int u,int v,int a,int b){e[cnt].to=v;e[cnt].a=a;e[cnt].b=b;e[cnt].Next=head[u];head[u]=cnt++;}
    void dfssz(int u,int f,int &sum)
    {
        sum++;sz[u]=1;
        for(int i=head[u];~i;i=e[i].Next)
        {
            int x=e[i].to;
            if(x==f||vis[x])continue;
            dfssz(x,u,sum);sz[u]+=sz[x];
        }
    }
    void dfszx(int u,int f,int sum,int &ans,int &id)
    {
        zx[u]=sum-sz[u];
        for(int i=head[u];~i;i=e[i].Next)
        {
            int x=e[i].to;
            if(x==f||vis[x])continue;
            dfszx(x,u,sum,ans,id);
            zx[u]=max(zx[u],sz[x]);
        }
        if(ans>zx[u]){ans=zx[u],id=u;}
    }
    int findzx(int root)
    {
        int sum=0;
        dfssz(root,-1,sum);
        int ans=inf,id=0;
        dfszx(root,-1,sum,ans,id);
        return id;
    }
    
    struct Point {
        ll x, y;
        Point(ll x = 0, ll y = 0) : x(x), y(y) {}
    };
    typedef Point Vector;
    Point operator + (Vector A, Vector B) {return Point(A.x + B.x, A.y + B.y);}
    Point operator - (Vector A, Vector B) {return Point(A.x - B.x, A.y - B.y);}
    bool operator == (const Vector &A, const Point &B) {return A.x == B.x&& A.y == B.y;}
    bool operator < (const Vector &A, const Vector &B) {return A.y < B.y || (A.y == B.y && A.x < B.x);}
    ll Cross(Vector A, Vector B) {return A.x * B.y - A.y * B.x;}
    int ConvexHull(Point *p, int n, Point *ch) {
        sort(p, p + n);
        int m = 0;
        for(int i = 0; i < n; i++) {
            while(m > 1 && Cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2]) <= 0) m--;
            ch[m++] = p[i];
        }
        int k = m;
        for(int i = n - 2; i >= 0; i--) {
            while(m > k && Cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2]) <= 0) m--;
            ch[m++] = p[i];
        }
        return n==1?m:m - 1;
    }
    int minkowski(Point *a,int &n,Point *b,int &m,Point *c,Point *d)
    {
        int top=0;
        if(n<=2||m<=2)
        {
            for(int i=0;i<n;i++)for(int j=0;j<m;j++)
                d[top++]=a[i]+b[j];
            top=ConvexHull(d,top,c);
            return top;
        }
        c[top++]=a[0]+b[0];
        for(int i=0,j=0;i<n||j<m;)
        {
            Point p1=a[i%n]+b[(j+1)%m],p2=a[(i+1)%n]+b[j%m];
            if(Cross(p1-c[top-1],p2-c[top-1])>=0)c[top++]=p1,++j;
            else c[top++]=p2,++i;
        }
        return top-1;
    }
    Point a[N*40],b[N],c[N*4],d[N*4],ans[N*40];
    vector<Point>v[N];
    int top,la,lb;
    void dfsdis(int u,int f,int root)
    {
        int num=0;
        for(int i=head[u];~i;i=e[i].Next)
        {
            int x=e[i].to;
            if(x==f||vis[x])continue;
            num++;
            dis[x].fi=dis[u].fi+e[i].a;
            dis[x].se=dis[u].se+e[i].b;
            dfsdis(x,u,root);
        }
        if(num==0)v[root].pb({dis[u].fi,dis[u].se});
    }
    void gao(int x)
    {
        la=0;
        for(int i=0;i<v[x].size();i++)a[la++]=v[x][i];
        lb=ConvexHull(a,la,b);v[x].clear();
        for(int i=0;i<lb;i++)v[x].pb(b[i]);
    }
    void solve(int root)
    {
        int p=findzx(root);
        v[0].clear();v[0].pb({0,0});
        set<pii>s;s.clear();s.insert(mp(v[0].size(),0));
        for(int i=head[p];~i;i=e[i].Next)
        {
            int x=e[i].to;if(vis[x])continue;
            v[x].clear();
            dis[x]=mp(e[i].a,e[i].b);dfsdis(x,p,x);
            gao(x);s.insert(mp(v[x].size(),x));
        }
        while(s.size()>=2)
        {
            int x=s.begin()->se;s.erase(s.begin());
            int y=s.begin()->se;s.erase(s.begin());
            la=lb=0;
            for(int i=0;i<v[x].size();i++)a[la++]=v[x][i];
            for(int i=0;i<v[y].size();i++)b[lb++]=v[y][i];
            int te=minkowski(a,la,b,lb,c,d);
            for(int i=0;i<te;i++)ans[top++]=c[i];
            for(int i=0;i<v[y].size();i++)v[x].pb(v[y][i]);v[y].clear();
            gao(x);s.insert(mp(v[x].size(),x));
        }
        vis[p]=1;
        for(int i=head[p];~i;i=e[i].Next)
        {
            int x=e[i].to;
            if(vis[x])continue;
            solve(e[i].to);
        }
    }
    int main()
    {
        int n=io.xint(),m=io.xint();
        init();
        for(int i=1;i<n;i++)
        {
            int u=io.xint(),v=io.xint(),a=io.xint(),b=io.xint();
            add(u,v,a,b);add(v,u,a,b);
        }
        solve(1);
        top=ConvexHull(ans,top,a);
        for(int i=0;i<m;i++)
        {
            int l=-1,r=top;
            while(l<r-6)
            {
                int m=(l+r)>>1,m1=(m+r)>>1;
                if(a[m].x*i+a[m].y>a[m1].x*i+a[m1].y)r=m1;
                else l=m;
            }
            ll ma=0;
            for(int j=max(0,l-10);j<min(top,l+10);j++)ma=max(ma,a[j].x*i+a[j].y);
            io.wint(ma);
        }
        return 0;
    }
    /********************
    
    ********************/
    
  • 相关阅读:
    《SQL Server 2008从入门到精通》--20180628
    2019国赛
    [蓝桥杯2020] 湖北省省赛
    2019第十届蓝桥杯B组决赛题解第五题
    试题 算法提高 分解质因数
    大数相加减
    试题 算法提高 汉诺塔
    试题 算法提高 欧拉函数
    试题 算法提高 天天向上-dp
    算法训练 猴子吃包子-构造
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/10617197.html
Copyright © 2011-2022 走看看