zoukankan      html  css  js  c++  java
  • bzoj千题计划276:bzoj4515: [Sdoi2016]游戏

    http://www.lydsy.com/JudgeOnline/problem.php?id=4515

    把lca带进式子,得到新的式子

    然后就是 维护树上一次函数取min

    一个调了一下午的错误:

    当一条线段完全在另一条线段之下时,用下面的完全覆盖上面的

    判断条件为  两线段在范围内没有交点

    然后若 新的线段的某一个端点<原来线段的对应的一个端点,就覆盖

    错误的写法:

    判断的时候 把两条线段在端点处相等也加了进去 

    即判断条件为  两线段在范围内没有交点 或 交点 在线段端点出

    那么 若 新的线段的某一个端点<=原来线段的对应的一个端点,就覆盖 

    不对!!

    因为交点在一个端点, 某一个端点<=原来线段的对应的一个端点,这个某一个交点 如果恰好是交点

    那么这两条线段谁覆盖谁都有可能

    所以应该是 若新线段有一个端点<原线段的对应端点,就覆盖

    因为 一直没有找出上面的错误,而且是后10个点WA,所以一气之下把所有的int替换成了long long。。。。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    #define N 100001
    
    #define min(x,y) ((x)<(y) ? (x) : (y))
    
    typedef long long LL;
    
    const LL inf=123456789123456789;
    
    long long n,m;
    
    long long front[N],nxt[N<<1],to[N<<1],val[N<<1],tot;
    
    long long fa[N],siz[N];
    LL dep[N];
    
    long long bl[N];
    long long id[N],tim,dy[N];
    
    LL mi[N<<2];
    LL mi_dep[N<<2],mx_dep[N<<2];
    int who[N<<2];
    LL tagA[N<<2],tagB[N<<2];
    long long L[N<<2],R[N<<2];
    bool have[N<<2];
        
    LL A,B;
        
    LL ans;
    
    bool zero;
    
    void read(long long &x)
    {
        x=0; long long f=1; char c=getchar();
        while(!isdigit(c)){ if(c=='-') f=-1; c=getchar(); }
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
        x*=f;
    }
    
    void add(long long u,long long v,long long w)
    {
        to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; val[tot]=w;
        to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; val[tot]=w;
    }
    
    void init()
    {
        read(n); read(m);
        long long u,v,w;
        for(long long i=1;i<n;++i)
        {
            read(u); read(v); read(w);
            add(u,v,w);
        }
    }
    
    void dfs1(long long x)
    {
        siz[x]=1;
        for(long long i=front[x];i;i=nxt[i])
            if(to[i]!=fa[x])
            {
                fa[to[i]]=x;
                dep[to[i]]=dep[x]+val[i]; 
                dfs1(to[i]);
                siz[x]+=siz[to[i]];
            }
    }
    
    void dfs2(long long x,long long top)
    {
        bl[x]=top;
        id[x]=++tim;
        dy[tim]=x;
        long long y=0;
        for(long long i=front[x];i;i=nxt[i])
            if(to[i]!=fa[x] && siz[to[i]]>siz[y]) y=to[i];
        if(!y) return;
        dfs2(y,top);
        for(long long i=front[x];i;i=nxt[i])
            if(to[i]!=fa[x] && to[i]!=y) dfs2(to[i],to[i]);
    }
    
    void build(long long k,long long l,long long r)
    {
        mi[k]=inf;
        L[k]=l;
        R[k]=r;
        if(l==r) 
        {
            mi_dep[k]=mx_dep[k]=dep[dy[l]];
            who[k]=dy[l];
            return;
        }
        long long mid=l+r>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
        mi_dep[k]=min(mi_dep[k<<1],mi_dep[k<<1|1]);
        mx_dep[k]=max(mx_dep[k<<1],mx_dep[k<<1|1]);
        if(mx_dep[k]==mx_dep[k<<1]) who[k]=who[k<<1];
        else who[k]=who[k<<1|1];
    }
    
    double get_point(LL k1,LL b1,LL k2,LL b2)
    {
        if(k1==k2) 
        {
            zero=true;
            return 0;
        }
        return 1.0*(b2-b1)/(k1-k2);
    }    
    
    void unionn_tag(long long k,LL tA,LL tB)
    {
        if(!have[k])
        {
            LL v;
            if(tA>0) v=tA*mi_dep[k]+tB;
            else v=tA*mx_dep[k]+tB;
            int kk=who[k];
            if(v<mi[k]) mi[k]=v;
            tagA[k]=tA;
            tagB[k]=tB;
            have[k]=true;
            return;
        }
        if(!(R[k]-L[k]))
        {
            if(tA>0) mi[k]=min(mi[k],tA*mi_dep[k]+tB);
            else mi[k]=min(mi[k],tA*mx_dep[k]+tB);
            return;
        }
        zero=false;
        double foot=get_point(tA,tB,tagA[k],tagB[k]);
        LL v1now=tA*dep[dy[R[k]]]+tB;
        LL v2now=tA*dep[dy[L[k]]]+tB;
        LL v1pre=tagA[k]*dep[dy[R[k]]]+tagB[k];
        LL v2pre=tagA[k]*dep[dy[L[k]]]+tagB[k];
        if(zero)
        {
            if(tB<tagB[k])
            {
                LL v;
                if(tA>0) v=tA*mi_dep[k]+tB;
                else v=tA*mx_dep[k]+tB;
                mi[k]=min(mi[k],v);
                tagA[k]=tA;
                tagB[k]=tB;
            }
            return;
        }
        if(foot<=dep[dy[L[k]]] || foot>=dep[dy[R[k]]])
        {
            if(v2now<v2pre || v1now<v1pre) 
            {
                tagA[k]=tA;
                tagB[k]=tB; 
                if(v1now>v2now) swap(v1now,v2now);
                mi[k]=min(mi[k],v1now);
            }     
            return;
        } 
        long long mid=L[k]+R[k]>>1;
        if(foot<=dep[dy[mid]])
        {
            if(v1now<=v1pre)
            {
                unionn_tag(k<<1,tagA[k],tagB[k]);
                tagA[k]=tA;
                tagB[k]=tB;
                if(v1now>v2now) swap(v1now,v2now);
                mi[k]=min(mi[k],v1now);
            }
            else
            {
                unionn_tag(k<<1,tA,tB);
                if(v1now>v2now) swap(v1now,v2now);
                mi[k]=min(mi[k],v1now);
            }
        }
        else
        {
            if(v1now<=v1pre)
            {
                unionn_tag(k<<1|1,tA,tB);
                if(v1now>v2now) swap(v1now,v2now);
                mi[k]=min(mi[k],v1now);
            }
            else
            {
                unionn_tag(k<<1|1,tagA[k],tagB[k]);
                tagA[k]=tA;
                tagB[k]=tB;
                if(v1now>v2now) swap(v1now,v2now);
                mi[k]=min(mi[k],v1now);
            }
        }
    } 
    
    void down(long long k)
    {
        if(!have[k]) return;
        unionn_tag(k<<1,tagA[k],tagB[k]);
        unionn_tag(k<<1|1,tagA[k],tagB[k]);
        tagA[k]=tagB[k]=0;
        have[k]=false;
    }    
    
    void change(long long k,long long l,long long r,long long opl,long long opr)
    {
        if(l>=opl && r<=opr)
        {
            unionn_tag(k,A,B);
            return;
        }
        down(k);
        long long mid=l+r>>1;
        if(opl<=mid) change(k<<1,l,mid,opl,opr);
        if(opr>mid) change(k<<1|1,mid+1,r,opl,opr);
        mi[k]=min(mi[k<<1],mi[k<<1|1]);
    }
    
    void Change(long long u,long long v)
    {
        while(bl[u]!=bl[v])
        {
            if(dep[bl[u]]<dep[bl[v]]) swap(u,v);
            change(1,1,n,id[bl[u]],id[u]);
            u=fa[bl[u]];
        }
        if(dep[u]>dep[v]) swap(u,v);
        change(1,1,n,id[u],id[v]);
    }
        
    void query(long long k,long long l,long long r,long long opl,long long opr)
    {
        if(l>=opl && r<=opr)
        {
            ans=min(ans,mi[k]);
            return;
        }
        down(k);
        long long mid=l+r>>1;
        if(opl<=mid) query(k<<1,l,mid,opl,opr);
        if(opr>mid) query(k<<1|1,mid+1,r,opl,opr); 
    }
        
    void Query(long long u,long long v)
    {
        while(bl[u]!=bl[v])
        {
            if(dep[bl[u]]<dep[bl[v]]) swap(u,v);
            query(1,1,n,id[bl[u]],id[u]);
            u=fa[bl[u]];
        }
        if(dep[u]>dep[v]) swap(u,v);
        query(1,1,n,id[u],id[v]);
    }
    
    long long get_lca(long long u,long long v)
    {
        while(bl[u]!=bl[v])
        {
            if(dep[bl[u]]<dep[bl[v]]) swap(u,v);
            u=fa[bl[u]];
        }
        return dep[u]<dep[v] ? u : v;
    }
    
    void out(LL x)
    {
        if(x>=10) out(x/10);
        putchar(x%10+'0');
    }
    
    void solve()
    {
        long long ty,s,t,a,b;
        long long lca;
        while(m--)
        {
            read(ty); read(s); read(t);
            lca=get_lca(s,t);
            if(ty==2)
            {
                ans=inf;
                Query(t,s);
                if(ans<0) putchar('-'),ans=-ans;
                out(ans);
                putchar('
    ');
            }
            else
            {
                read(a); read(b); 
                lca=get_lca(s,t);
                A=-a; B=a*dep[s]+b;
            //    printf("%I64d
    ",(dep[s]-dep[7])*a+b);
                Change(lca,s);
                A=a; B=(dep[s]-2*dep[lca])*a+b;
            //    printf("%I64d
    ",(dep[s]+dep[7]-2*dep[lca])*a+b);
                Change(lca,t);
            }
        }
    }
    
    int main()
    {
        init();
        dfs1(1);
        dfs2(1,1);
        //for(int i=1;i<=n;++i) printf("%d
    ",bl[i]); 
        build(1,1,n);
        solve();
        return 0;
    }
  • 相关阅读:
    (二)vue的生命周期及相关的运行流程
    Vue接入百度地图显示及相关操作
    前端开发环境的介绍
    更改博客园的样式
    Ant Design of Vue 组件库的使用
    Vue 更换页面图标和title
    (四) Vue 相关的路由配置(及子路由配置)
    SVN创建分支的相关操作
    vs code插件自动压缩 min.css
    敲开通往架构师的门
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8561309.html
Copyright © 2011-2022 走看看