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;
    }
  • 相关阅读:
    《Django By Example》第十二章(终章) 中文 翻译 (个人学习,渣翻)
    《Django By Example》第十一章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第十章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第九章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第八章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第五章 中文 翻译 (个人学习,渣翻)
    我的superui开源后台bootstrap开发框架
    LayoutInflater 总结
    Android屏幕分辨率概念(dp、dip、dpi、sp、px)
    android studio安装问题
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8561309.html
Copyright © 2011-2022 走看看