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('\n');
        }
        else
        {
            read(a); read(b); 
            lca=get_lca(s,t);
            A=-a; B=a*dep[s]+b;
        //    printf("%I64d\n",(dep[s]-dep[7])*a+b);
            Change(lca,s);
            A=a; B=(dep[s]-2*dep[lca])*a+b;
        //    printf("%I64d\n",(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\n",bl[i]); 
    build(1,1,n);
    solve();
    return 0;
}

 

posted @ 2018-03-13 20:16  TRTTG  阅读(257)  评论(0编辑  收藏  举报