P4374 [USACO18OPEN]Disruption P
https://www.luogu.com.cn/problem/P4374
洛谷这题一言难尽
添加新边影响的边只有与新边成环的所有边,那就很简单了,树链剖分树上最大值就行了。。。很简单不知道为啥是紫题
#include<iostream> #include<vector> #include<queue> #include<stack> #include<algorithm> using namespace std; const int maxn = 2e5+11; const int INF = 1e9+111; vector<int>G[maxn]; void add(int be,int en){ G[be].push_back(en); } int n,m; int top[maxn],id[maxn],cnt,dep[maxn],fa[maxn],siz[maxn],son[maxn]; int dfs(int x,int f,int d) { fa[x] = f; dep[x] = d; siz[x] = 1; int s = 0; for(int i=0; i< G[x].size(); i++) { int p = G[x][i]; if(p == f) continue; dfs(p,x,d+1); siz[x] += siz[p]; if(s < siz[p]) { s = siz[p]; son[x] = p; } } return 0; } int dfs2(int x,int t) { id[x] = ++cnt; top[x] = t; if(son[x] != 0) dfs2(son[x],t); for(int i=0; i<G[x].size(); i++) { int p =G[x][i]; if(p == son[x] || p == fa[x]) continue; dfs2(p,p); } return 0; } //建立线段树 struct Node { int ans,lazy; } tree[maxn*4]; int bulit(int node,int be,int en) { int mid =be+en>>1; int l = node*2; int r = node*2+1; if(be == en) { tree[node].ans = INF; tree[node].lazy = INF; return 0; } tree[node].ans = INF; tree[node].lazy = INF; bulit(l,be,mid); bulit(r,mid+1,en); return 0; } int push(int node,int be,int en) { int mid = be +en >>1; int l = node*2; int r = node*2+1; if(tree[node].lazy != INF) { tree[l].ans = min(tree[l].ans , tree[node].lazy); tree[r].ans = min(tree[r].ans , tree[node].lazy); tree[l].lazy = min(tree[node].lazy,tree[l].lazy); tree[r].lazy = min(tree[node].lazy,tree[r].lazy); tree[node].lazy = INF; } return 0; } int update(int node,int be,int en,int LL,int RR,int val) { if(LL > RR) return 0; int mid = be +en >>1; int l = node*2; int r = node*2+1; if(LL <= be && en <= RR) { tree[node].ans = min(tree[node].ans ,val); if(tree[node].lazy != 0) tree[node].lazy = min(tree[node].lazy,val); return 0; } push(node,be,en); if(LL <= mid) update(l,be,mid,LL,RR,val); if(RR > mid) update(r,mid+1,en,LL,RR,val); tree[node].ans = min(tree[l].ans,tree[r].ans); return 0; } int ask(int node,int be,int en,int LL,int RR) { if(LL > RR) return INF; int mid = be + en >> 1; int l = node*2; int r = node*2+1; if(LL <= be && en <= RR) { return tree[node].ans; } int a = INF,b = INF; push(node,be,en); if(LL <= mid) a = ask(l,be,mid,LL,RR); if(RR > mid) b = ask(r,mid+1,en,LL,RR); return min(a,b); } int change(int x,int y,int val) { int ans = INF; while(top[x] != top[y]) { if(dep[top[x]] < dep[top[y]]) swap(x,y); update(1,1,n,id[top[x]],id[x],val); x = fa[top[x]]; } if(dep[x] > dep[y]) swap(x,y); update(1,1,n,id[x] + 1,id[y],val); return 0; } vector<pair<int,int> >ins; vector<int>ans; int main() { // freopen("in.in","r",stdin); // freopen("out.out","w",stdout); scanf("%d %d",&n,&m); for(int i=1; i<n; i++) { int be,en; scanf("%d%d",&be,&en); ins.push_back(make_pair(be,en)); add(be,en); add(en,be); } dfs(1,-1,1); dfs2(1,1); bulit(1,1,n); while(m--) { int x,y,w; scanf("%d %d %d",&x,&y,&w); change(x,y,w); } for(int i=0;i<ins.size();i++){ int x = ins[i].first; int y = ins[i].second; if(dep[x] < dep[y]) swap(x,y); int a = ask(1,1,n,id[x],id[x]); ans.push_back(a); } for(int i=0;i<ans.size();i++){ if(ans[i] == INF) ans[i] = -1; printf("%d\n",ans[i]); } return 0; }
寻找真正的热爱