1 条题解
-
0Guest LV 0 MOD
-
0
这题其实很简单的,只是把几个模板套在了一起而已.首先可以分析危险系数最边最小路径一定在最小生成树上,然后这题实际上就转化为了一个树链问题,用一个简单的树链剖分和线段树维护就可以搞了.
#include<bits/stdc++.h> #define LL long long const int maxn=1e6; const LL mod=1e9+7; inline const void read(LL &a) { char c=getchar();LL b=1;a=0; while(c<'0'||c>'9'){if(c=='-')b=-1;c=getchar();} while(c>='0'&&c<='9') { a=(a<<1)+(a<<3)+c-'0'; c=getchar(); } a*=b; } inline const void write(LL a) { if(a<0){putchar('-');a=-a;} if(a>9)write(a/10); putchar(a%10+'0'); } inline const LL min(LL a,LL b) { if(a<b)return a; return b; } inline const LL max(LL a,LL b) { if(a>b)return a; return b; } LL n,m,t,d=0; LL from[maxn],to[maxn],next[maxn],point[maxn]; inline const void add(LL a,LL b) { next[++d]=point[a]; to[d]=b; point[a]=d; } struct side { LL from,to,next,height; }s[maxn]; inline const bool comp(const side&a,const side&b) { if(a.height<b.height)return true; return false; } struct LEAST_TREE { LL belong[maxn]; inline const LL check(LL a) { if(a==belong[a])return a; return belong[a]=check(belong[a]); } void solve() { for(LL i=1;i<=n;i++)belong[i]=i; memset(point,false,sizeof(point)); for(LL i=1;i<=m;i++){read(s[i].from);read(s[i].to);read(s[i].height);} std::sort(s+1,s+1+m,comp); LL k=n-1,t=1; while(k) { if(check(s[t].from)==check(s[t].to)){t++;continue;} belong[check(s[t].from)]=s[t].to; add(s[t].from,s[t].to); add(s[t].to,s[t].from); k--;t++; } } }least_tree; LL father[maxn],top[maxn],deep[maxn]; LL leaf[maxn],order=0,pos[maxn],init[maxn]; struct LINK_CUT_TREE { LL son[maxn],num[maxn]; bool vis[maxn]; inline const void dfs1(LL p) { vis[p]=true; LL side=point[p]; num[p]=1; while(side) { if(!vis[to[side]]) { father[to[side]]=p; deep[to[side]]=deep[p]+1; dfs1(to[side]); num[p]+=num[to[side]]; if(num[to[side]]>num[son[p]])son[p]=to[side]; } side=next[side]; } } inline const void dfs2(LL p,LL t) { vis[p]=true;top[p]=t; leaf[++order]=p;pos[p]=order; if(son[p]&&!vis[son[p]])dfs2(son[p],t); LL side=point[p]; while(side) { if(!vis[to[side]]&&to[side]!=son[p])dfs2(to[side],to[side]); side=next[side]; } } void solve() { memset(father,0,sizeof(father)); memset(son,0,sizeof(son)); memset(deep,0,sizeof(deep)); memset(vis,false,sizeof(vis)); dfs1(1); memset(vis,false,sizeof(vis)); dfs2(1,1); } }link_cut_tree; struct SEGMENT_TREE { LL love[maxn<<2],col[maxn<<2],sum; inline const void update(LL p) { love[p]=max(love[p<<1],love[p<<1|1]); } inline const void build(LL p,LL l,LL r) { if(l==r){love[p]=init[leaf[++order]];return ;} LL mid=(l+r)>>1; build(p<<1,l,mid); build(p<<1|1,mid+1,r); update(p); } inline const void push_col(LL p) { if(col[p]) { col[p<<1]+=col[p];col[p<<1|1]+=col[p]; love[p<<1]+=col[p];love[p<<1|1]+=col[p]; col[p]=0; } } inline const LL query(LL p,LL l,LL r,LL ll,LL rr) { if(l>=ll&&r<=rr)return love[p]; push_col(p); LL mid=(l+r)>>1,ans=-INT_MAX; if(mid>=ll)ans=max(ans,query(p<<1,l,mid,ll,rr)); if(mid+1<=rr)ans=max(ans,query(p<<1|1,mid+1,r,ll,rr)); return ans; } inline const void modify(LL p,LL l,LL r,LL ll,LL rr,LL mark) { if(l>=ll&&r<=rr) { col[p]+=mark;love[p]+=mark; return ; } push_col(p); LL mid=(l+r)>>1; if(mid>=ll)modify(p<<1,l,mid,ll,rr,mark); if(mid+1<=rr)modify(p<<1|1,mid+1,r,ll,rr,mark); update(p); } void solve() { sum=order=0; build(1,1,n); memset(col,0,sizeof(col)); while(t) { t--; LL start,end,ans=-INT_MAX,change; read(start);read(end);read(change); while(top[start]!=top[end]) { if(deep[top[start]]>deep[top[end]]) { modify(1,1,n,pos[top[start]],pos[start],change); ans=max(ans,query(1,1,n,pos[top[start]],pos[start])); start=father[top[start]]; } else { modify(1,1,n,pos[top[end]],pos[end],change); ans=max(ans,query(1,1,n,pos[top[end]],pos[end])); end=father[top[end]]; } } if(deep[start]>deep[end]) { modify(1,1,n,pos[end],pos[start],change); ans=max(ans,query(1,1,n,pos[end],pos[start])); } else { modify(1,1,n,pos[start],pos[end],change); ans=max(ans,query(1,1,n,pos[start],pos[end])); } sum=(sum+ans)%mod; } write(sum);printf("\n");write(query(1,1,n,1,n)); } }segment_tree; int main() { read(n);read(m);read(t); for(LL i=1;i<=n;i++)read(init[i]); least_tree.solve(); link_cut_tree.solve(); segment_tree.solve(); return 0; }
- 1
信息
- 难度
- 9
- 分类
- (无)
- 标签
- (无)
- 递交数
- 10
- 已通过
- 1
- 通过率
- 10%
- 上传者