zoukankan      html  css  js  c++  java
  • 932F Escape Through Leaf

    传送门

    题目大意

    https://www.luogu.org/problemnew/show/CF932F

    分析

    我们可以从叶子向根每次插入b和ans

    所以我们不难发现就是相当于插入线段

    于是李超树+线段树合并即可

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<ctime>
    #include<queue>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    #define int long long
    const int maxm = 2e5;
    const int M = 1e5;
    struct node {
        int k,b,le,ri;
    };
    node d[4000000];
    int n,m,a[100100],b[100100],rt[100100],ans[100100],cnt,sum,Ans;
    bool vis[4000000];
    vector<int>v[100100];
    inline int get(int b1,int k1,int b2,int k2){return (b2-b1)/(k1-k2);}
    inline void add(int le,int ri,int wh,int B,int K){
        if(!vis[wh]){
          d[wh].k=K;
          d[wh].b=B;
          vis[wh]=1;
          return;
        }
        int f1=K*(le-M)+B,f2=d[wh].k*(le-M)+d[wh].b,f3=K*(ri-M)+B,f4=d[wh].k*(ri-M)+d[wh].b;
        if(f1>=f2&&f3>=f4)return;
        if(f1<=f2&&f3<=f4)d[wh].k=K,d[wh].b=B;
          else {
              int mid=(le+ri)>>1;
              int x=get(B,K,d[wh].b,d[wh].k)+M;
              if(f1<=f2){
                if(x>mid)d[wh].ri=(d[wh].ri?d[wh].ri:++cnt),
                            add(mid+1,ri,d[wh].ri,d[wh].b,d[wh].k),d[wh].k=K,d[wh].b=B;
                  else d[wh].le=(d[wh].le?d[wh].le:++cnt),
                         add(le,mid,d[wh].le,B,K);
              }else {
                if(x<=mid)d[wh].le=(d[wh].le?d[wh].le:++cnt),
                           add(le,mid,d[wh].le,d[wh].b,d[wh].k),d[wh].k=K,d[wh].b=B;
                  else d[wh].ri=(d[wh].ri?d[wh].ri:++cnt),
                         add(mid+1,ri,d[wh].ri,B,K);
              }
          }
    }
    inline void que(int le,int ri,int wh,int x){
        if(!wh)return;
        if(vis[wh])Ans=min(Ans,(x-M)*d[wh].k+d[wh].b);
        if(le==ri)return;
        int mid=(le+ri)>>1;
        if(mid>=x)que(le,mid,d[wh].le,x);
          else que(mid+1,ri,d[wh].ri,x);
    }
    inline int mer(int le,int ri,int x,int y){
        if(!x||!y)return x+y; 
        int mid=(le+ri)>>1;
        d[x].le=mer(le,mid,d[x].le,d[y].le);
        d[x].ri=mer(mid+1,ri,d[x].ri,d[y].ri);
        add(le,ri,x,d[y].b,d[y].k);
        return x;
    }
    inline void dfs(int x,int fa){
        for(int i=0;i<v[x].size();i++)
          if(v[x][i]!=fa){
              dfs(v[x][i],x);
              rt[x]=mer(0,maxm,rt[x],rt[v[x][i]]);
          }
        Ans=1000000000000000007ll;
        if(!rt[x])rt[x]=++cnt;
        que(0,maxm,rt[x],a[x]+M);
        if(v[x].size()==1&&v[x][0]==fa)Ans=0;
        ans[x]=Ans;
        add(0,maxm,rt[x],ans[x],b[x]);
    }
    signed main(){
        int i,j,k;
        scanf("%lld",&n);
        for(i=1;i<=n;i++)scanf("%lld",&a[i]);
        for(i=1;i<=n;i++)scanf("%lld",&b[i]);
        for(i=1;i<n;i++){
          int x,y;
          scanf("%lld%lld",&x,&y);
          v[x].push_back(y);
          v[y].push_back(x);
        }
        for(i=1;i<4000000;i++)d[i].le=d[i].ri=d[i].k=d[i].b=0;
        dfs(1,0);
        for(i=1;i<=n;i++)printf("%lld ",ans[i]);
        return 0;
    }
  • 相关阅读:
    Rotate Image
    Color Sort
    Chapter 3: Binary Tree
    Different Ways to Add Parentheses
    最短路径问题
    Longest Palindromic Substring
    Word Break
    PCA和SVD简述
    Set Matrix Zeros
    星级评价
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/10406235.html
Copyright © 2011-2022 走看看