线段树合并模板题
不说了直接代码分析
大佬的code
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map> #include<vector> #include<queue> #include<ctime> using namespace std; #define ll long long #define N 101000 #define Z 100000 #define inf 1e9 #define RG register #define re return inline ll read(){ RG ll x=0,t=1;RG char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=-1,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return x*t; } int n,m,top,first[N],ans[N]; struct mona {int nxt,en;}s[N<<1]; struct joker{int nxt,en,op;}; inline void Insert(int x,int y) { s[++top]=(mona){first[x],y}; first[x]=top; } struct SeqTree{ int cnt,ls[N*40],rs[N*40],Max[N*40],id[N*40],rt[N],rab[N*40],tot,top,first[N]; joker s[N<<2]; inline void Insert(int x,int y,int op) //差分起始 { s[++top]=(joker){first[x],y,op}; first[x]=top; } inline int New() { if(tot) re rab[tot--]; re ++cnt; } inline void Throw(int x) { rab[++top]=x; ls[x]=rs[x]=Max[x]=id[x]=0; } inline void Pushup(int x) { if(Max[ls[x]]>=Max[rs[x]]) Max[x]=Max[ls[x]],id[x]=id[ls[x]]; else Max[x]=Max[rs[x]],id[x]=id[rs[x]]; } inline void Modify(int l,int r,int &x,int pos,int val) { if(!x) x=New(); if(l==r) { Max[x]+=val; id[x]=l; } else { int mid=l+r>>1; if(pos<=mid) Modify(l,mid,ls[x],pos,val); else Modify(mid+1,r,rs[x],pos,val); Pushup(x); } if(!Max[x]) id[x]=0;//回收机制处理 } inline int Merge(int l,int r,int u,int v)//并一波线段树 { if(!u||!v) return u|v; int now=New(),mid=l+r>>1; if(l==r) Max[now]=Max[u]+Max[v],id[now]=l;//MAX,id同步 else { ls[now]=Merge(l,mid,ls[u],ls[v]); rs[now]=Merge(mid+1,r,rs[u],rs[v]); Pushup(now); } Throw(u); Throw(v); //biu,扔进垃圾桶 re now; } } T; struct Tree{ int top[N],son[N],siz[N],fa[N],dep[N]; inline void Dfs(int k,int Fa){ fa[k]=Fa,siz[k]=1,dep[k]=dep[Fa]+1; for(RG int i=first[k];i;i=s[i].nxt){ int en=s[i].en; if(en==Fa) continue ; Dfs(en,k),siz[k]+=siz[en]; if(siz[son[k]]<siz[en]) son[k]=en; } return ; } inline void Dfs2(int k,int to){ top[k]=to; if(son[k]) Dfs2(son[k],to); for(RG int i=first[k];i;i=s[i].nxt){ int en=s[i].en; if(en==fa[k]||en==son[k]) continue ; Dfs2(en,en); } } inline int Lca(int u,int v){ while(top[u]!=top[v]){ if(dep[top[u]]<dep[top[v]]) swap(u,v); u=fa[top[u]]; } return dep[u]<dep[v]?u:v; } } S;//LCA树 inline void Dfs(int k,int fa) { for(RG int i=first[k];i;i=s[i].nxt) if(s[i].en!=fa) Dfs(s[i].en,k); for(RG int i=T.first[k];i;i=T.s[i].nxt) T.Modify(1,Z,T.rt[k],T.s[i].en,T.s[i].op);//加入 ans[k]=T.id[T.rt[k]]; if(S.fa[k])//存在父亲 T.rt[S.fa[k]]=T.Merge(1,Z,T.rt[S.fa[k]],T.rt[k]); //并 re; } int main(){ freopen("in.txt","r",stdin); n=read(),m=read(); for(RG int i=1;i<n;++i) { int x=read(),y=read(); Insert(x,y),Insert(y,x);//add边 } //剖一波 S.Dfs(1,0); S.Dfs2(1,1); for(RG int i=1;i<=m;++i) { int u=read(),v=read(),val=read(); int lca=S.Lca(u,v),Flca=S.fa[lca];//LCA //差分一下 T.Insert(u,val,1),T.Insert(v,val,1),T.Insert(lca,val,-1),T.Insert(Flca,val,-1); } Dfs(1,0); //总来一起统计 for(RG int i=1;i<=n;++i) printf("%d\n",ans[i]); }
蒟蒻的
有一点问题就是
权值线段树
貌似可以不用离散化
/* while(next second) ++love_life; */ #include<bits/stdc++.h> #define re return #define R register #define inc(i,l,r) for(register int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } const int maxn=1e5+5,maxl=1e5; int n,m,k,hd[maxn],hide[maxn],X[maxn],Y[maxn],Z[maxn],a[maxn]; int ans[maxn]; struct node{ int to,nt; }e[maxn<<1]; inline void add(int x,int y) { e[++k].to=y;e[k].nt=hd[x];hd[x]=k; e[++k].to=x;e[k].nt=hd[y];hd[y]=k; } struct tree { int first[maxn],top,tot,cnt; int rab[maxn*30],rt[maxn*30],id[maxn*30],ls[maxn*30],rs[maxn*30],Max[maxn*30]; struct LL { int col,nt,op; }st[maxn<<2]; inline void insert(int x,int y,int z) //节点X染成y,+-z { st[++top].col=y;st[top].nt=first[x];first[x]=top;st[top].op=z; } inline int New() { int now; if(tot)now=rab[tot--]; else now=++cnt; ls[now]=rs[now]=Max[now]=0; re now; } inline void Throw(int x) { rab[++tot]=x; } inline void pushup(int rt) { if(Max[ls[rt]]<Max[rs[rt]]) Max[rt]=Max[rs[rt]],id[rt]=id[rs[rt]]; else Max[rt]=Max[ls[rt]],id[rt]=id[ls[rt]]; } inline void Add(int &rt,int l,int r,int pos,int val) { if(!rt) rt=New(); if(l==r) { Max[rt]+=val; id[rt]=l; re; } int mid=(l+r)>>1; if(pos<=mid) Add(ls[rt],l,mid,pos,val); else Add(rs[rt],mid+1,r,pos,val); pushup(rt); if(!Max[rt]) id[rt]=0; } inline int merge(int l,int r,int x,int y) { if(!x||(!y))re x+y; if(l==r) { Max[x]+=Max[y]; Throw(y); re x; } int mid=(l+r)>>1; ls[x]=merge(l,mid,ls[x],ls[y]); rs[x]=merge(mid+1,r,rs[x],rs[y]); Throw(y); pushup(x); re x; } }T; struct LCA { int fa[maxn],top[maxn],son[maxn],size[maxn],dep[maxn]; inline void dfs1(int x) { dep[x]=dep[fa[x]]+(size[x]=1); for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; if(v==fa[x])continue; fa[v]=x; dfs1(v); size[x]+=size[v]; if(size[v]>size[son[x]]) son[x]=v; } } inline void dfs2(int x,int topf) { top[x]=topf; if(son[x]) { dfs2(son[x],topf); for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; if(!top[v]) dfs2(v,v); } } } inline int Lca(int x,int y) { while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]])x^=y^=x^=y; x=fa[top[x]]; } re dep[x]<dep[y]?x:y; } }S; inline void dfs(int x) { for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; if(v==S.fa[x])continue; dfs(v); } for(int i=T.first[x];i;i=T.st[i].nt) T.Add(T.rt[x],1,maxl,T.st[i].col,T.st[i].op); ans[x]=T.id[T.rt[x]]; if(S.fa[x])T.rt[S.fa[x]]=T.merge(1,maxl,T.rt[S.fa[x]],T.rt[x]); } int main() { freopen("in.txt","r",stdin); int x,y,z; rd(n),rd(m); inc(i,2,n) { rd(x),rd(y); add(x,y); } S.dfs1(1); S.dfs2(1,1); inc(i,1,m) { rd(X[i]),rd(Y[i]),rd(Z[i]); a[i]=Z[i]; } //离散化 sort(a+1,a+m+1); int N=unique(a+1,a+m+1)-a-1; inc(i,1,N)hide[i]=a[i]; inc(i,1,m) { int lca=S.Lca(X[i],Y[i]),flca=S.fa[lca]; int pos=lower_bound(a+1,a+N+1,Z[i])-a; T.insert(X[i],pos,1);T.insert(Y[i],pos,1); T.insert(lca,pos,-1);T.insert(flca,pos,-1); } dfs(1); inc(i,1,n) printf("%d\n",hide[ans[i]]); re 0; }