• 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;
    }
  • 相关阅读:
    神经网络LeNet5的 的 FPGA RTL级实现 4
    LeNet5 MNIST 的 FPGA实现 3
    NGINX 代理转发 FTP/SFTP
    macOS开发 NSTextField控件 macOS中并没有 UILable ,也没有 NSLabel
    macOS WKwebview的简单实现
    Mac下更新Python3
    macOS 预览和截屏 关于上架app store的有效截图尺寸
    macOS Hardened Runtime is not enabled.must be rebuilt with support for the Hardened Runtime
    Cornerstone已损坏,无法打开。 您应该将它移到废纸篓。
    macOS开发 设置鼠标放在控件上是否有小手
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8561309.html
Copyright © 2020-2023  润新知