[树链剖分]JZOJ 5914 盟主的忧虑
分析
这题显然密道会密道两端到LCA中经过的边的值
这不就是树链剖分嘛
写个区间修改走人
什么?并查集做法?不会
#include <iostream> #include <cstdio> #include <cstring> #define rep(i,a,b) for (i=a;i<=b;i++) using namespace std; const int N=1e5+10; struct Node { int sz,f,s,seg,top,dep; }a[N]; int scnt,rev[N]; struct Edge { int u,v,nx; }g[2*N]; int cnt,list[N]; int t[4*N],lz[4*N]; int mn; int n,m; void Add(int u,int v) {g[++cnt].u=u;g[cnt].v=v;g[cnt].nx=list[u];list[u]=cnt;} void Dfs1(int x,int f) { a[x].f=f;a[x].dep=a[f].dep+1;a[x].sz=1; for (int i=list[x];i;i=g[i].nx) if (g[i].v!=f) { Dfs1(g[i].v,x); a[x].sz+=a[g[i].v].sz; if (a[g[i].v].sz>a[a[x].s].sz) a[x].s=g[i].v; } } void Dfs2(int x,int f) { int son=a[x].s; if (son) { a[son].seg=++scnt; rev[scnt]=son; a[son].top=a[x].top; Dfs2(son,x); } for (int i=list[x];i;i=g[i].nx) if (!a[g[i].v].top) { a[g[i].v].seg=++scnt; rev[scnt]=g[i].v; a[g[i].v].top=g[i].v; Dfs2(g[i].v,x); } } void Build(int x,int l,int r) { if (l==r) { t[x]=2147483647; return; } int mid=l+r>>1; Build(x<<1,l,mid);Build((x<<1)+1,mid+1,r); t[x]=2147483647; } void Pushdown(int x) { if (lz[x]) { t[x<<1]=lz[x<<1]=min(!lz[x<<1]?2147483647:lz[x<<1],lz[x]); t[(x<<1)+1]=lz[(x<<1)+1]=min(!lz[(x<<1)+1]?2147483647:lz[(x<<1)+1],lz[x]); lz[x]=0; } } void Change_In_Segment(int x,int l,int r,int val,int ll,int rr) { if (ll>rr) return; if (l>rr||ll>r) return; if (ll<=l&&r<=rr) { t[x]=min(t[x],val); lz[x]=min(!lz[x]?2147483647:lz[x],val); return; } Pushdown(x); int mid=l+r>>1; if (mid>=ll) Change_In_Segment(x<<1,l,mid,val,ll,rr); if (mid<rr) Change_In_Segment((x<<1)+1,mid+1,r,val,ll,rr); t[x]=min(t[x<<1],t[(x<<1)+1]); } void Query_In_Segment(int x,int l,int r,int ll,int rr) { if (ll>rr) return; if (r<ll||l>rr) return; if (ll<=l&&r<=rr) { mn=min(mn,t[x]); return; } Pushdown(x); int mid=l+r>>1; if (ll<=mid) Query_In_Segment(x<<1,l,mid,ll,rr); if (mid+1<=rr) Query_In_Segment((x<<1)+1,mid+1,r,ll,rr); } void Query_In_Tree(int x,int y) { int fx=a[x].top,fy=a[y].top; while (fx!=fy) { if (a[fx].dep<a[fy].dep) swap(x,y),swap(fx,fy); Query_In_Segment(1,1,scnt,a[fx].seg,a[x].seg); x=a[fx].f;fx=a[x].top; } if (a[x].dep>a[y].dep) swap(x,y); Query_In_Segment(1,1,scnt,a[x].seg+1,a[y].seg); } void Change_In_Tree(int x,int y,int val) { int fx=a[x].top,fy=a[y].top; while (fx!=fy) { if (a[fx].dep<a[fy].dep) swap(x,y),swap(fx,fy); Change_In_Segment(1,1,scnt,val,a[fx].seg,a[x].seg); x=a[fx].f;fx=a[x].top; } if (a[x].dep>a[y].dep) swap(x,y); Change_In_Segment(1,1,scnt,val,a[x].seg+1,a[y].seg); } int main() { freopen("worry.in","r",stdin); freopen("worry.out","w",stdout); int i; char s[20]; scanf("%d%d",&n,&m); rep(i,1,n-1) { int u,v; scanf("%d%d",&u,&v); Add(u,v);Add(v,u); } Dfs1(1,0); scnt=1; a[1].seg=a[1].top=rev[1]=1; Dfs2(1,0); Build(1,1,scnt); for (int i=1;i<=m;i++) { int x,y,w; scanf("%d%d%d",&x,&y,&w); Change_In_Tree(x,y,w); } for (int i=1;i<=n-1;i++) { mn=2147483647; Query_In_Tree(g[i*2-1].u,g[i*2-1].v); printf("%d\n",mn==2147483647?-1:mn); } }
在日渐沉没的世界里,我发现了你。