您的位置:首页 > 其它

bzoj千题计划276:bzoj4515: [Sdoi2016]游戏

2018-03-13 20:16 337 查看
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
,nxt[N<<1],to[N<<1],val[N<<1],tot;

long long fa
,siz
;
LL dep
;

long long bl
;
long long id
,tim,dy
;

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: