社区讨论
蒟蒻求助,样例第二个输出0
P4069[SDOI2016] 游戏参与者 4已保存回复 7
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 7 条
- 当前快照
- 1 份
- 快照标识符
- @lo8nks0j
- 此快照首次捕获于
- 2023/10/27 21:32 2 年前
- 此快照最后确认于
- 2023/10/27 21:32 2 年前
不知道为啥第一次修改后mn就变成0了
CPP#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5,inf=123456789123456789;
int n,m,cnt,id[N],sum,dep[N],dis[N],re[N],f[N][30],top[N],t[N<<2],sz[N],mn[N],son[N],head[N],tot;
struct o{
int ne,to,dis;
}e[N<<1];
inline void add(int x,int y,int k){
e[++tot].ne=head[x];
head[x]=tot;
e[tot].to=y;
e[tot].dis=k;
}
struct oo{
int k,b;
}a[N];
inline int y(oo a,int x){
return a.k*x+a.b;
}
inline void dfs1(int x,int fa){
f[x][0]=fa;
sz[x]=1;
dep[x]=dep[fa]+1;
for(int i=1;i<=log2(dep[x]);i++){
f[x][i]=f[f[x][i-1]][i-1];
}
for(int i=head[x];i;i=e[i].ne){
int to=e[i].to;
if(to==fa)continue;
dis[to]=dis[x]+e[i].dis;
dfs1(to,x);
sz[x]+=sz[to];
if(sz[to]>sz[son[x]])son[x]=to;
}
}
inline void dfs2(int x,int tp){
top[x]=tp;
id[x]=++sum;
re[sum]=x;
if(!son[x])return;
dfs2(son[x],tp);
for(int i=head[x];i;i=e[i].ne){
int to=e[i].to;
if(to==f[x][0]||to==son[x])continue;
dfs2(to,to);
}
}
inline int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
while(dep[x]>dep[y]){
x=f[x][(int)log2(dep[x]-dep[y])];
}
if(x==y)return x;
for(int i=20;~i;i--){
if(f[x][i]!=f[y][i]){
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
inline void pushup(int x,int l,int r){
int ll=dis[re[l]],rr=dis[re[r]];
mn[x]=min(mn[x],min(mn[x<<1],mn[x<<1|1]));
mn[x]=min(mn[x],min(y(a[t[x]],ll),y(a[t[x]],rr)));
}
inline void update(int x,int l,int r,int ql,int qr,int k){
if(l>qr||r<ql)return;
int mid=(l+r)>>1;
if(l>=ql&&r<=qr){
int ll=dis[re[l]],rr=dis[re[r]],mi=dis[re[mid]];
if(y(a[k],mi)<y(a[t[x]],mi))swap(t[x],k);
if(y(a[k],ll)<y(a[t[x]],ll))update(x<<1,l,mid,ql,qr,k);
if(y(a[k],rr)<y(a[t[x]],rr))update(x<<1|1,mid+1,r,ql,qr,k);
pushup(x,l,r);
return;
}
update(x<<1,l,mid,ql,qr,k);
update(x<<1|1,mid+1,r,ql,qr,k);
pushup(x,l,r);
return;
}
inline int ask(int x,int l,int r,int ql,int qr){
if(l>qr||r<ql)return 3e18;
if(l>=ql&&r<=qr){
return mn[x];
}
int mid=(l+r)>>1;
int ans=min(y(a[t[x]],dis[re[max(l,ql)]]),y(a[t[x]],dis[re[min(r,qr)]]));
ans=min(ans,min(ask(x<<1,l,mid,ql,qr),ask(x<<1|1,mid+1,r,ql,qr)));
return ans;
}
inline void change(int x,int y,int k){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
update(1,1,n,id[top[x]],id[x],k);
x=f[top[x]][0];
}
if(id[x]>id[y])swap(x,y);
update(1,1,n,id[x],id[y],k);
return;
}
inline int query(int x,int y){
int ans=inf;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans=min(ans,ask(1,1,n,id[top[x]],id[x]));
x=f[top[x]][0];
}
if(id[x]>id[y])swap(x,y);
ans=min(ans,ask(1,1,n,id[x],id[y]));
return ans;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>m;
memset(mn,0x3f,sizeof(mn));
for(int i=1;i<n;i++){
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
add(v,u,w);
}
dfs1(1,0);
dfs2(1,1);
for(int i=1;i<=m;i++){
int op,s,t;
cin>>op>>s>>t;
if(op==1){
int k,b;
cin>>k>>b;
int fa=lca(s,t);
a[++cnt]=(oo){-k,k*dis[s]+b};
change(s,fa,cnt);
a[++cnt]=(oo){k,k*dis[s]-2*k*dis[fa]+b};
change(fa,t,cnt);
}else cout<<query(s,t)<<'\n';
}
return 0;
}
回复
共 7 条回复,欢迎继续交流。
正在加载回复...