树链剖分【LIST】

it2023-11-20  109

P2146 [NOI2015]软件包管理器 #include<bits/stdc++.h> using namespace std; const int N=1e5+100; int head[N],ver[N<<1],edge[N<<1],nex[N<<1]; int tot=0; void addedge(int x,int y,int z){ ver[++tot]=y,nex[tot]=head[x]; edge[tot]=z;head[x]=tot; } int d[N]; int top[N]; int dfn[N]; int rnk[N]; int fa[N]; int siz[N]; int son[N]; int cnt=0; #define lc (p<<1) #define rc (p<<1|1) #define mid ((t[p].l+t[p].r)>>1) struct Segment{ int l,r; int dat,alz; }t[N<<2]; void pushup(int p){ t[p].dat=t[lc].dat+t[rc].dat; } void build(int p,int l,int r){ t[p].l=l,t[p].r=r; t[p].alz=0; if(l==r){ t[p].dat=0; return; } build(lc,l,mid); build(rc,mid+1,r); pushup(p); } void spread(int p){ if(t[p].alz!=-1){ t[lc].dat=(t[lc].r-t[lc].l+1)*t[p].alz; t[rc].dat=(t[rc].r-t[rc].l+1)*t[p].alz; t[lc].alz=t[rc].alz=t[p].alz; t[p].alz=-1; } } void update(int p,int l,int r,int val){ if(l<=t[p].l&&t[p].r<=r){ t[p].dat=(t[p].r-t[p].l+1)*val; t[p].alz=val; return; } spread(p); if(l<=mid) update(lc,l,r,val); if(r>mid) update(rc,l,r,val); pushup(p); } int query(int p,int l,int r){ if(l<=t[p].l&&t[p].r<=r){ return t[p].dat; } spread(p); int val=0; if(l<=mid) val+=query(lc,l,r); if(r>mid) val+=query(rc,l,r); return val; } void dfs1(int x,int f){ d[x]=d[f]+1; siz[x]=1; fa[x]=f; int maxson=-1; for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y==f) continue; dfs1(y,x); siz[x]+=siz[y]; if(maxson<siz[y]) maxson=siz[y],son[x]=y; } } void dfs2(int x,int t){ top[x]=t; dfn[x]=++cnt; rnk[cnt]=x; if(!son[x]) return; dfs2(son[x],t); for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y!=fa[x]&&y!=son[x]) dfs2(y,y); } } void updRange(int x,int y,int val){ while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); update(1,dfn[top[x]],dfn[x],val); x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); update(1,dfn[x],dfn[y],val); } int qRange(int x,int y){ int ans=0; while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); ans+=query(1,dfn[top[x]],dfn[x]); x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); ans+=query(1,dfn[x],dfn[y]); return ans; } int qSon(int x){ return query(1,dfn[x],dfn[x]+siz[x]-1); } void updSon(int x,int val){ return update(1,dfn[x],dfn[x]+siz[x]-1,val); } int main(){ int n; cin>>n; for(int i=1;i<=n-1;i++){ int x; cin>>x; x++; addedge(i+1,x,1); addedge(x,i+1,1); } dfs1(1,0); dfs2(1,1); build(1,1,n); int m; cin>>m; for(int i=1;i<=m;i++){ string op; int x; cin>>op>>x; x++; if(op=="install"){ int last=qRange(1,x); updRange(1,x,1); int now=qRange(1,x); cout<<now-last<<endl; } else{ int last=qSon(x); updSon(x,0); int now=qSon(x); cout<<last-now<<endl; } } return 0; } P2590 [ZJOI2008]树的统计 #include<bits/stdc++.h> using namespace std; #define ll long long const int N=1e5+100; const int INF=0X3F3F3F3F; int tot=0; int head[N],ver[N<<1],nex[N<<1],edge[N<<1]; void addedge(int x,int y,int z){ ver[++tot]=y,nex[tot]=head[x]; edge[tot]=z;head[x]=tot; } int d[N]; int rnk[N]; int top[N]; int cnt=0; int son[N]; int siz[N]; int dfn[N]; int w[N]; int fa[N]; #define lc (p<<1) #define rc (p<<1|1) #define mid ((t[p].l+t[p].r)>>1) struct Segment{ int l,r; ll dat,mx; }t[N<<2]; void pushup(int p){ t[p].dat=t[lc].dat+t[rc].dat; t[p].mx=max(t[lc].mx,t[rc].mx); } void build(int p,int l,int r){ t[p].l=l,t[p].r=r; if(l==r){ t[p].dat=t[p].mx=w[rnk[l]]; return; } build(lc,l,mid); build(rc,mid+1,r); pushup(p); } void update(int p,int l,int r,int val){ if(l<=t[p].l&&t[p].r<=r){ t[p].dat=t[p].mx=val; return; } if(l<=mid) update(lc,l,r,val); if(r>mid) update(rc,l,r,val); pushup(p); } ll query_sum(int p,int l,int r){ if(l<=t[p].l&&t[p].r<=r) { return t[p].dat; } ll val=0; if(l<=mid) val=(val+query_sum(lc,l,r)); if(r>mid) val=(val+query_sum(rc,l,r)); return val; } ll query_max(int p,int l,int r){ if(l<=t[p].l&&t[p].r<=r){ return t[p].mx; } ll val=-INF; if(l<=mid) val=max(val,query_max(lc,l,r)); if(r>mid) val=max(val,query_max(rc,l,r)); return val; } /*********************************************/ void dfs1(int x,int f){ d[x]=d[f]+1; siz[x]=1; fa[x]=f; int maxson=-1; for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y==f) continue; dfs1(y,x); siz[x]+=siz[y]; if(siz[y]>maxson) son[x]=y,maxson=siz[y]; } } void dfs2(int x,int t){ dfn[x]=++cnt; top[x]=t; rnk[cnt]=x; if(!son[x]) return; dfs2(son[x],t); for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y!=son[x]&&y!=fa[x]) dfs2(y,y); } } int qSum(int x,int y){ int ans=0; while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); int res=query_sum(1,dfn[top[x]],dfn[x]); ans=(ans+res); x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); int res=query_sum(1,dfn[x],dfn[y]); ans=(ans+res); return ans; } int qMax(int x,int y){ int ans=-INF; while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); int res=query_max(1,dfn[top[x]],dfn[x]); ans=max(ans,res); x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); int res=query_max(1,dfn[x],dfn[y]); ans=max(ans,res); return ans; } void updRange(int x,int val){ update(1,dfn[x],dfn[x],val); } int main(){ int n; cin>>n; for(int i=1;i<=n-1;i++){ int x,y; cin>>x>>y; addedge(x,y,1); addedge(y,x,1); } for(int i=1;i<=n;i++) cin>>w[i]; dfs1(1,0); dfs2(1,1); build(1,1,n); int m; cin>>m; for(int i=1;i<=m;i++){ string op; int x,y,val; cin>>op; if(op=="QMAX"){ cin>>x>>y; cout<<qMax(x,y)<<endl; } else if(op=="QSUM"){ cin>>x>>y; cout<<qSum(x,y)<<endl; } else{ cin>>x>>val; updRange(x,val); } } return 0; } P3038 [USACO11DEC]Grass Planting G #include<bits/stdc++.h> using namespace std; #define ll long long const int N=1e5+100; int head[N],ver[N<<1],edge[N<<1],nex[N<<1]; int tot=0; void addedge(int x,int y,int z){ ver[++tot]=y,nex[tot]=head[x]; edge[tot]=z,head[x]=tot; } int d[N]; int dfn[N]; int fa[N]; int siz[N]; int son[N]; int rnk[N]; int top[N]; int cnt=0; #define lc (p<<1) #define rc (p<<1|1) #define mid ((t[p].l+t[p].r)>>1) #define lc (p<<1) #define rc (p<<1|1) #define mid ((t[p].l+t[p].r)>>1) struct Segment{ int l,r; ll dat,alz; }t[N<<2]; void pushup(int p){ t[p].dat=t[lc].dat+t[rc].dat; } void build(int p,int l,int r){ t[p].l=l,t[p].r=r; t[p].alz=0; if(l==r){ t[p].dat=0; return; } build(lc,l,mid); build(rc,mid+1,r); pushup(p); } void spread(int p){ if(t[p].alz){ t[lc].dat+=(t[lc].r-t[lc].l+1)*t[p].alz; t[rc].dat+=(t[rc].r-t[rc].l+1)*t[p].alz; t[lc].alz+=t[p].alz; t[rc].alz+=t[p].alz; t[p].alz=0; } } void update(int p,int l,int r,ll val){ if(l<=t[p].l&&t[p].r<=r){ t[p].dat+=(t[p].r-t[p].l+1)*val; t[p].alz+=val; return; } spread(p); if(l<=mid) update(lc,l,r,val); if(r>mid) update(rc,l,r,val); pushup(p); } ll query(int p,int l,int r){ if(l<=t[p].l&&t[p].r<=r){ return t[p].dat; } spread(p); ll val=0; if(l<=mid) val+=query(lc,l,r); if(r>mid) val+=query(rc,l,r); return val; } void updRange(int x,int y,ll val){ while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); update(1,dfn[top[x]],dfn[x],val); x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); update(1,dfn[x]+1,dfn[y],val); } ll qRange(int x,int y){ ll ans=0; while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); ans+=query(1,dfn[top[x]],dfn[x]); x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); ans+=query(1,dfn[x]+1,dfn[y]); return ans; } void dfs1(int x,int f){ fa[x]=f; d[x]=d[f]+1; siz[x]=1; int maxson=-1; for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y==f) continue; dfs1(y,x); siz[x]+=siz[y]; if(maxson<siz[y]) maxson=siz[y],son[x]=y; } } void dfs2(int x,int t){ top[x]=t; dfn[x]=++cnt; rnk[cnt]=x; if(!son[x]) return; dfs2(son[x],t); for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y!=fa[x]&&y!=son[x]) dfs2(y,y); } } int main(){ int n,m; cin>>n>>m; for(int i=1;i<=n-1;i++){ int x,y; cin>>x>>y; addedge(x,y,1); addedge(y,x,1); } dfs1(1,0); dfs2(1,1); build(1,1,n); for(int i=1;i<=m;i++){ char op; int x,y; cin>>op>>x>>y; if(op=='P'){ updRange(x,y,1); } else{ cout<<qRange(x,y)<<endl; } } return 0; } P3128 [USACO15DEC]Max Flow P #include<bits/stdc++.h> using namespace std; #define ll long long const int N=1e5+100; int head[N],nex[N<<1],edge[N<<1],ver[N<<1]; int tot=0; void addedge(int x,int y,int z){ ver[++tot]=y,nex[tot]=head[x],head[x]=tot; edge[tot]=z; } int d[N]; int top[N]; int fa[N]; int son[N]; int siz[N]; int cnt=0; int dfn[N]; int rnk[N]; #define lc (p<<1) #define rc (p<<1|1) #define mid ((t[p].l+t[p].r)>>1) struct Segment{ int l,r; ll dat,alz; }t[N<<2]; void pushup(int p){ t[p].dat=max(t[lc].dat,t[rc].dat); } void build(int p,int l,int r){ t[p].l=l,t[p].r=r; t[p].alz=0; if(l==r){ t[p].dat=0; return; } build(lc,l,mid); build(rc,mid+1,r); pushup(p); } void spread(int p){ if(t[p].alz){ t[lc].dat+=t[p].alz; t[rc].dat+=t[p].alz; t[lc].alz+=t[p].alz; t[rc].alz+=t[p].alz; t[p].alz=0; } } void update(int p,int l,int r,int val){ if(l<=t[p].l&&t[p].r<=r){ t[p].dat+=val; t[p].alz+=val; return ; } spread(p); if(l<=mid) update(lc,l,r,val); if(r>mid) update(rc,l,r,val); pushup(p); } ll query(int p,int l,int r){ if(l<=t[p].l&&t[p].r<=r) return t[p].dat; spread(p); ll val=0; if(l<=mid) val+=query(lc,l,r); if(r>mid) val+=query(rc,l,r); return val; } void dfs1(int x,int f){ d[x]=d[f]+1; fa[x]=f; siz[x]=1; int maxson=-1; for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y==f) continue; dfs1(y,x); siz[x]+=siz[y]; if(maxson<siz[y]) maxson=siz[y],son[x]=y; } } void dfs2(int x,int t){ top[x]=t; dfn[x]=++cnt; rnk[cnt]=x; if(!son[x]) return; dfs2(son[x],t); for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y!=fa[x]&&y!=son[x]) dfs2(y,y); } } void updRange(int x,int y,int val){ while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); update(1,dfn[top[x]],dfn[x],val); x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); update(1,dfn[x],dfn[y],val); } int n,m; void test(){ cout<<"dfn"<<endl; for(int i=1;i<=n;i++) printf("dfn[%d]=%d\n",i,dfn[i]); } int main(){ cin>>n>>m; for(int i=1;i<=n-1;i++){ int x,y; cin>>x>>y; addedge(x,y,1); addedge(y,x,1); } dfs1(1,0); dfs2(1,1); build(1,1,n); //test(); while(m--){ int x,y; cin>>x>>y; updRange(x,y,1); //cout<<query(1,1,n)<<endl; } cout<<query(1,1,n)<<endl; return 0; } P3178 [HAOI2015]树上操作 #include<bits/stdc++.h> using namespace std; const int N=1e5+100; #define ll long long int head[N],ver[N<<1],edge[N<<1],nex[N<<1]; int tot=0; void addedge(int x,int y,int z){ ver[++tot]=y,nex[tot]=head[x],edge[tot]=z; head[x]=tot; } int d[N]; int top[N]; int dfn[N]; int siz[N]; int son[N]; int rnk[N]; ll w[N]; int fa[N]; int cnt=0; #define lc (p<<1) #define rc (p<<1|1) #define mid ((t[p].l+t[p].r)>>1) struct Segment{ ll l,r; ll dat,alz; }t[N<<2]; void pushup(int p){ t[p].dat=t[lc].dat+t[rc].dat; } void build(int p,int l,int r){ t[p].l=l,t[p].r=r; t[p].alz=0; if(l==r){ t[p].dat=w[rnk[l]]; return ; } build(lc,l,mid); build(rc,mid+1,r); pushup(p); } void spread(int p){ if(t[p].alz){ t[lc].dat+=(t[lc].r-t[lc].l+1)*t[p].alz; t[rc].dat+=(t[rc].r-t[rc].l+1)*t[p].alz; t[lc].alz+=t[p].alz; t[rc].alz+=t[p].alz; t[p].alz=0; } } ll query(int p,int l,int r){ if(l<=t[p].l&&t[p].r<=r) { return t[p].dat; } spread(p); ll val=0; if(l<=mid) val=(val+query(lc,l,r)); if(r>mid) val=(val+query(rc,l,r)); return val; } void update(int p,int l,int r,ll val){ if(l<=t[p].l&&t[p].r<=r){ t[p].dat+=(t[p].r-t[p].l+1)*val; t[p].alz=(t[p].alz+val); return; } spread(p); if(l<=mid) update(lc,l,r,val); if(r>mid) update(rc,l,r,val); pushup(p); } void dfs1(int x,int f){ d[x]=d[f]+1; siz[x]=1; fa[x]=f; int maxson=-1; for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y==f) continue; dfs1(y,x); siz[x]+=siz[y]; if(siz[y]>maxson) son[x]=y,maxson=siz[y]; } } void dfs2(int x,int t){ dfn[x]=++cnt; top[x]=t; rnk[cnt]=x; if(!son[x]) return; dfs2(son[x],t); for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y!=son[x]&&y!=fa[x]) dfs2(y,y); } } void updDot(int x,ll val){ update(1,dfn[x],dfn[x],val); } ll qRange(int x,int y){ ll ans=0; while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); ll res=query(1,dfn[top[x]],dfn[x]); ans=(ans+res); x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); ll res=query(1,dfn[x],dfn[y]); ans=(ans+res); return ans; } void updSon(int x,ll val){ update(1,dfn[x],dfn[x]+siz[x]-1,val); } int main(){ int n,m; cin>>n>>m; for(int i=1;i<=n;i++) cin>>w[i]; for(int i=1;i<=n-1;i++){ int x,y; cin>>x>>y; addedge(x,y,1); addedge(y,x,1); } dfs1(1,0); dfs2(1,1); build(1,1,n); for(int i=1;i<=m;i++){ ll x,k,op; cin>>op; if(op==1){ cin>>x>>k; updDot(x,k); } else if(op==2){ cin>>x>>k; updSon(x,k); } else{ cin>>x; cout<<qRange(1,x)<<endl; } } return 0; } P3384 【模板】轻重链剖分 #include<bits/stdc++.h> using namespace std; #define ll long long const int N=1e5+100; #define gc getchar int read(){ int res=0,f=1; char ch=gc(); while(!isdigit(ch)) f^=ch=='-',ch=gc(); while(isdigit(ch)) res=(res<<1)+(res<<3)+(ch^48),ch=gc(); return res; } int tot=0; int head[N],edge[N<<1],ver[N<<1],nex[N<<1]; void addedge(int x,int y,int z ){ ver[++tot]=y,nex[tot]=head[x]; edge[tot]=z;head[x]=tot; } int son[N],dfn[N],fa[N],rnk[N],cnt=0; int d[N],siz[N],top[N]; #define lc (p<<1) #define rc (p<<1|1) #define mid ((t[p].l+t[p].r)>>1) struct Segment{ int l,r; ll dat,alz; }t[N<<2]; int mod; int n,root,m,w[N]; void pushup(int p){ t[p].dat=(t[lc].dat+t[rc].dat)%mod; } void build(int p,int l,int r){ t[p].l=l,t[p].r=r; t[p].alz=0; if(l==r) { t[p].dat=rnk[l]; return; } build(lc,l,mid); build(rc,mid+1,r); pushup(p); } void spread(int p){ if(t[p].alz){ t[lc].dat+=(t[lc].r-t[lc].l+1)*t[p].alz; t[lc].dat%=mod; t[rc].dat+=(t[rc].r-t[rc].l+1)*t[p].alz; t[rc].dat%=mod; t[lc].alz=(t[lc].alz+t[p].alz)%mod; t[rc].alz=(t[rc].alz+t[p].alz)%mod; t[p].alz=0; } } ll query(int p,int l,int r){ if(l<=t[p].l&&t[p].r<=r) { return t[p].dat; } spread(p); ll val=0; if(l<=mid) val=(val+query(lc,l,r))%mod; if(r>mid) val=(val+query(rc,l,r))%mod; return val; } void update(int p,int l,int r,int val){ if(l<=t[p].l&&t[p].r<=r){ t[p].dat+=(t[p].r-t[p].l+1)*val; t[p].dat%=mod; t[p].alz=(t[p].alz+val)%mod; return; } spread(p); if(l<=mid) update(lc,l,r,val); if(r>mid) update(rc,l,r,val); pushup(p); } /********************************************/ void dfs1(int x,int f){ d[x]=d[f]+1; siz[x]=1; fa[x]=f; int maxson=-1; for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y==f) continue; dfs1(y,x); siz[x]+=siz[y]; if(siz[y]>maxson) son[x]=y,maxson=siz[y]; } } void dfs2(int x,int t){ dfn[x]=++cnt; top[x]=t; rnk[cnt]=w[x]; if(!son[x]) return; dfs2(son[x],t); for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y!=son[x]&&y!=fa[x]) dfs2(y,y); } } int qRange(int x,int y){ int ans=0; while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); int res=query(1,dfn[top[x]],dfn[x]); ans=(ans+res)%mod; x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); int res=query(1,dfn[x],dfn[y]); ans=(ans+res)%mod; return ans; } void updRange(int x,int y,int val){ val%=mod; while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); update(1,dfn[top[x]],dfn[x],val); x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); update(1,dfn[x],dfn[y],val); } int qSon(int x){ int res=query(1,dfn[x],dfn[x]+siz[x]-1); return res; } void updSon(int x,int val){ update(1,dfn[x],dfn[x]+siz[x]-1,val); } int main(){ n=read(),m=read(),root=read(),mod=read(); for(int i=1;i<=n;i++) w[i]=read(); for(int i=1;i<=n-1;i++){ int x=read(),y=read(); addedge(x,y,1); addedge(y,x,1); } dfs1(root,0); dfs2(root,root); build(1,1,n); for(int i=1;i<=m;i++){ int op=read(); int x,y,k; if(op==1){ x=read(),y=read(),k=read(); updRange(x,y,k); } else if(op==2){ x=read(),y=read(); printf("%d\n",qRange(x,y)); } else if(op==3){ x=read(),k=read(); updSon(x,k); } else if(op==4){ x=read(); printf("%d\n",qSon(x)); } } return 0; } P3833 [SHOI2012]魔法树 #include<bits/stdc++.h> using namespace std; #define ll long long const int N=1e5+100; int head[N],edge[N<<1],ver[N<<1],nex[N<<1]; int tot; void addedge(int x,int y,int z){ ver[++tot]=y,nex[tot]=head[x]; edge[tot]=z,head[x]=tot; } int d[N]; int top[N]; int fa[N]; int siz[N]; int dfn[N]; int rnk[N]; int son[N]; int cnt=0; #define lc (p<<1) #define rc (p<<1|1) #define mid ((t[p].l+t[p].r)>>1) struct Segment{ int l,r; ll dat,alz; }t[N<<2]; void pushup(int p){ t[p].dat=t[lc].dat+t[rc].dat; } void build(int p,int l,int r){ t[p].l=l,t[p].r=r; t[p].alz=0; if(l==r){ t[p].dat=0; return; } build(lc,l,mid); build(rc,mid+1,r); pushup(p); } void spread(int p){ if(t[p].alz){ t[lc].dat+=(t[lc].r-t[lc].l+1)*t[p].alz; t[rc].dat+=(t[rc].r-t[rc].l+1)*t[p].alz; t[lc].alz+=t[p].alz; t[rc].alz+=t[p].alz; t[p].alz=0; } } void update(int p,int l,int r,ll val){ if(l<=t[p].l&&t[p].r<=r){ t[p].dat+=(t[p].r-t[p].l+1)*val; t[p].alz+=val; return; } spread(p); if(l<=mid) update(lc,l,r,val); if(r>mid) update(rc,l,r,val); pushup(p); } ll query(int p,int l,int r){ if(l<=t[p].l&&t[p].r<=r){ return t[p].dat; } spread(p); ll val=0; if(l<=mid) val+=query(lc,l,r); if(r>mid) val+=query(rc,l,r); return val; } void updRange(int x,int y,ll val){ while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); update(1,dfn[top[x]],dfn[x],val); x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); update(1,dfn[x],dfn[y],val); } ll qSon(int x){ return query(1,dfn[x],dfn[x]+siz[x]-1); } void dfs1(int x,int f){ fa[x]=f; siz[x]=1; d[x]=d[f]+1; ll maxson=-1; for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y==f) continue; dfs1(y,x); siz[x]+=siz[y]; if(maxson<siz[y]) son[x]=y,maxson=siz[y]; } } void dfs2(int x,int t){ top[x]=t; dfn[x]=++cnt; rnk[cnt]=x; if(!son[x]) return; dfs2(son[x],t); for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y!=fa[x]&&y!=son[x]) dfs2(y,y); } } int main(){ int n; cin>>n; for(int i=1;i<=n-1;i++){ int x,y; cin>>x>>y; x++,y++; addedge(x,y,1); addedge(y,x,1); } dfs1(1,0); dfs2(1,1); build(1,1,n); int m; cin>>m; while(m--){ char op; int x,y; ll val; cin>>op; if(op=='A'){ cin>>x>>y>>val; x++,y++; updRange(x,y,val); } else if(op=='Q'){ cin>>x; x++; cout<<qSon(x)<<endl; } } return 0; } P4092 [HEOI2016/TJOI2016]树 #include<bits/stdc++.h> using namespace std; #define ll long long const int N=1e5+100; int head[N],ver[N<<1],edge[N<<1],nex[N<<1]; int tot=0; void addedge(int x,int y,int z){ ver[++tot]=y,nex[tot]=head[x]; edge[tot]=z,head[x]=tot; } int d[N]; int cnt=0; int siz[N]; int top[N]; int son[N]; int fa[N]; int rnk[N]; int dfn[N]; #define lc (p<<1) #define rc (p<<1|1) #define mid ((t[p].l+t[p].r)>>1) struct Segment{ int l,r; ll dat; }t[N<<2]; void pushup(int p){ t[p].dat=max(t[lc].dat,t[rc].dat); } void build(int p,int l,int r){ t[p].l=l,t[p].r=r; t[p].dat=-1; if(l==r) return; build(lc,l,mid); build(rc,mid+1,r); } void update(int p,int l,int r){ if(l<=t[p].l&&t[p].r<=r){ t[p].dat=t[p].l; return; } if(l<=mid) update(lc,l,r); if(r>mid) update(rc,l,r); pushup(p); } int query(int p,int l,int r){ if(l<=t[p].l&&t[p].r<=r) return t[p].dat; int val=-1; if(l<=mid) val=max(val,query(lc,l,r)); if(r>mid) val=max(val,query(rc,l,r)); return val; } void dfs1(int x,int f){ d[x]=d[f]+1; siz[x]=1; fa[x]=f; int maxson=-1; for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y==f) continue; dfs1(y,x); siz[x]+=siz[y]; if(maxson<siz[y]) maxson=siz[y],son[x]=y; } } void dfs2(int x,int t){ top[x]=t; dfn[x]=++cnt; rnk[cnt]=x; if(!son[x]) return; dfs2(son[x],t); for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y!=fa[x]&&y!=son[x]) dfs2(y,y); } } void updRange(int x,int y){ if(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); update(1,dfn[top[x]],dfn[x]); x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); update(1,dfn[x],dfn[y]); } int qRange(int x,int y){ int ans=-1; while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); ans=query(1,dfn[top[x]],dfn[x]); if(ans!=-1) return rnk[ans]; x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); ans=query(1,dfn[x],dfn[y]); return rnk[ans]; } int main(){ int n,m; cin>>n>>m; for(int i=1;i<=n-1;i++){ int x,y; cin>>x>>y; addedge(x,y,1); addedge(y,x,1); } dfs1(1,0); dfs2(1,1); build(1,1,n); updRange(1,1); for(int i=1;i<=m;i++){ char op; int x; cin>>op>>x; if(op=='C'){ updRange(x,x); } else{ cout<<qRange(1,x)<<endl; } } return 0; } P4114 Qtree1 #include<bits/stdc++.h> using namespace std; const int N=1e5+100; const int INF=0x3f3f3f3f; #define ll long long int head[N],edge[N<<1],nex[N<<1],ver[N<<1]; int tot=0; void addedge(int x,int y,int z){ ver[++tot]=y,nex[tot]=head[x]; edge[tot]=z,head[x]=tot; } int d[N]; int cnt=0; int siz[N]; int top[N]; int son[N]; int fa[N]; int rnk[N]; int dfn[N]; int u[N],v[N],w[N]; #define lc (p<<1) #define rc (p<<1|1) #define mid ((t[p].l+t[p].r)>>1) struct Segment{ int l,r; ll dat; }t[N<<2]; void pushup(int p){ t[p].dat=max(t[lc].dat,t[rc].dat); } void build(int p,int l,int r){ t[p].l=l,t[p].r=r; if(l==r){ t[p].dat=w[rnk[l]]; return; } build(lc,l,mid); build(rc,mid+1,r); pushup(p); } void update(int p,int l,int r,int val){ if(l<=t[p].l&&t[p].r<=r){ t[p].dat=val; return; } if(l<=mid) update(lc,l,r,val); if(r>mid) update(rc,l,r,val); pushup(p); } ll query(int p,int l,int r){ if(l<=t[p].l&&t[p].r<=r){ return t[p].dat; } ll val=-INF; if(l<=mid) val=max(val,query(lc,l,r)); if(r>mid) val=max(val,query(rc,l,r)); return val; } void dfs1(int x,int f){ fa[x]=f; d[x]=d[f]+1; siz[x]=1; int maxson=-1; for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y==f) continue; w[y]=edge[i]; dfs1(y,x); siz[x]+=siz[y]; if(maxson<siz[y]) maxson=siz[y],son[x]=y; } } void dfs2(int x,int t){ top[x]=t; dfn[x]=++cnt; rnk[cnt]=x; if(!son[x]) return; dfs2(son[x],t); for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y!=fa[x]&&y!=son[x]) dfs2(y,y); } } ll qRange(int x,int y){ ll ans=-1; while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); ans=max(ans,query(1,dfn[top[x]],dfn[x])); x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); ans=max(ans,query(1,dfn[x]+1,dfn[y])); return ans; } void updRange(int x,int y,int val){ while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); update(1,dfn[top[x]],dfn[x],val); x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); update(1,dfn[x],dfn[y],val); } int main(){ int n; cin>>n; for(int i=1;i<=n-1;i++){ int x,y,z; cin>>x>>y>>z; addedge(x,y,z); addedge(y,x,z); u[i]=x,v[i]=y; } dfs1(1,0); dfs2(1,1); build(1,1,n); while(1){ string op; int x,y; cin>>op; if(op=="DONE") break; else if(op=="QUERY"){ cin>>x>>y; if(x==y) cout<<0<<endl; else cout<<qRange(x,y)<<endl; } else{ int i,k; cin>>i>>k; int x=u[i],y=v[i]; if(fa[y]==x) swap(x,y); updRange(x,x,k); } } return 0; } P4116 Qtree3 #include<bits/stdc++.h> using namespace std; #define ll long long const int N=1e5+100; const int INF=0x3f3f3f3f; int head[N],ver[N<<1],edge[N<<1],nex[N<<1]; int tot=0; void addedge(int x,int y,int z){ ver[++tot]=y,edge[tot]=z; nex[tot]=head[x],head[x]=tot; } int d[N]; int dfn[N]; int rnk[N]; int siz[N]; int fa[N]; int son[N]; int top[N]; int cnt=0; #define lc (p<<1) #define rc (p<<1|1) #define mid ((t[p].l+t[p].r)>>1) struct Segment{ int l,r; int dat; }t[N<<2]; void pushup(int p){ t[p].dat=min(t[lc].dat,t[rc].dat); } void build(int p,int l,int r){ t[p].l=l,t[p].r=r; t[p].dat=INF; if(l==r) return; build(lc,l,mid); build(rc,mid+1,r); pushup(p); } void update(int p,int l,int r){ if(l<=t[p].l&&t[p].r<=r){ if(t[p].dat==INF) t[p].dat=t[p].l; else t[p].dat=INF; return; } if(l<=mid) update(lc,l,r); if(r>mid) update(rc,l,r); pushup(p); } int query(int p,int l,int r){ if(l<=t[p].l&&t[p].r<=r){ return t[p].dat; } int val=INF; if(l<=mid) val=min(val,query(lc,l,r)); if(r>mid) val=min(val,query(rc,l,r)); return val; } void dfs1(int x,int f){ fa[x]=f; d[x]=d[f]+1; siz[x]=1; int maxson=-1; for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y==f) continue; dfs1(y,x); siz[x]+=siz[y]; if(maxson<siz[y]) maxson=siz[y],son[x]=y; } } void dfs2(int x,int t){ top[x]=t; dfn[x]=++cnt; rnk[cnt]=x; if(!son[x]) return; dfs2(son[x],t); for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y!=fa[x]&&y!=son[x]) dfs2(y,y); } } void updDot(int x){ update(1,dfn[x],dfn[x]); } int qRange(int x,int y){ int ans=INF; while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); ans=min(ans,query(1,dfn[top[x]],dfn[x])); x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); ans=min(ans,query(1,dfn[x],dfn[y])); if(ans==INF) return -1; else return rnk[ans]; } int main(){ int n,m; cin>>n>>m; for(int i=1;i<=n-1;i++){ int x,y; cin>>x>>y; addedge(x,y,1); addedge(y,x,1); } dfs1(1,0); dfs2(1,1); build(1,1,n); while(m--){ int op,x; cin>>op>>x; if(op==0) updDot(x); else cout<<qRange(1,x)<<endl; } return 0; } P4281 [AHOI2008]紧急集合 / 聚会 #include<bits/stdc++.h> using namespace std; const int N=5e5+100; int head[N],nex[N<<1],edge[N<<1],ver[N<<1]; int tot=0; void addedge(int x,int y,int z){ ver[++tot]=y,nex[tot]=head[x]; edge[tot]=z;head[x]=tot; } int d[N]; int fa[N]; int dfn[N]; int cnt=0; int siz[N]; int top[N]; int son[N]; void dfs1(int x,int f){ d[x]=d[f]+1; siz[x]=1; fa[x]=f; int maxson=-1; for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y==f) continue; dfs1(y,x); siz[x]+=siz[y]; if(maxson<siz[y]) maxson=siz[y],son[x]=y; } } void dfs2(int x,int t){ top[x]=t; dfn[x]=++cnt; if(!son[x]) return; dfs2(son[x],t); for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y!=fa[x]&&y!=son[x]) dfs2(y,y); } } int getlca(int x,int y){ while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); x=fa[top[x]]; } if(d[x]<d[y]) return x; else return y; } int getdist(int x,int y){ return d[x]+d[y]-2*d[getlca(x,y)]; } int main(){ int n,m; cin>>n>>m; for(int i=1;i<=n-1;i++){ int x,y; cin>>x>>y; addedge(x,y,1); addedge(y,x,1); } dfs1(1,0); dfs2(1,1); for(int i=1;i<=m;i++){ int x,y,z; cin>>x>>y>>z; int c=0x3f3f3f3f; int ans; int lca=getlca(x,y); int dist=getdist(x,y)+getdist(z,lca); if(c>dist){ c=dist,ans=lca; } lca=getlca(z,y); dist=getdist(z,y)+getdist(x,lca); if(c>dist){ c=dist,ans=lca; } lca=getlca(x,z); dist=getdist(x,z)+getdist(y,lca); if(c>dist){ c=dist,ans=lca; } printf("%d %d\n",ans,c); } return 0; } P4315 月下“毛景树” #include<bits/stdc++.h> using namespace std; const int N=1e5+100; #define ll long long int head[N],nex[N<<1],edge[N<<1],ver[N<<1]; int tot=0; void addedge(int x,int y,int z){ ver[++tot]=y,nex[tot]=head[x]; edge[tot]=z,head[x]=tot; } int d[N]; int top[N]; int dfn[N]; int rnk[N]; int fa[N]; int son[N]; int siz[N]; int cnt=0; int u[N],v[N],w[N]; #define lc (p<<1) #define rc (p<<1|1) #define mid ((t[p].l+t[p].r)>>1) struct Segment{ int l,r; ll dat,alz,wlz; }t[N<<2]; void pushup(int p){ t[p].dat=max(t[lc].dat,t[rc].dat); } void build(int p,int l,int r){ t[p].l=l,t[p].r=r; t[p].alz=0; t[p].wlz=-1; if(l==r){ t[p].dat=w[rnk[l]]; //printf("%d: %d\n",t[p].l,t[p].dat); return; } build(lc,l,mid); build(rc,mid+1,r); pushup(p); } void spread(int p){ if(t[p].wlz>=0){ t[lc].dat=t[rc].dat=t[p].wlz; t[lc].wlz=t[rc].wlz=t[p].wlz; t[lc].alz=t[rc].alz=0; t[p].wlz=-1; } if(t[p].alz){ t[lc].dat+=t[p].alz; t[rc].dat+=t[p].alz; t[lc].alz+=t[p].alz; t[rc].alz+=t[p].alz; t[p].alz=0; } } void updsame(int p,int l,int r,int val){ if(l<=t[p].l&&t[p].r<=r){ t[p].wlz=val; t[p].alz=0; t[p].dat=val; return; } spread(p); if(l<=mid) updsame(lc,l,r,val); if(r>mid) updsame(rc,l,r,val); pushup(p); } void updadd(int p,int l,int r,int val){ if(l<=t[p].l&&t[p].r<=r){ t[p].alz+=val; t[p].dat+=val; return; } spread(p); if(l<=mid) updadd(lc,l,r,val); if(r>mid) updadd(rc,l,r,val); pushup(p); } int query(int p,int l,int r){ if(l<=t[p].l&&t[p].r<=r) return t[p].dat; spread(p); int val=-1; if(l<=mid) val=max(val,query(lc,l,r)); if(r>mid) val=max(val,query(rc,l,r)); return val; } void dfs1(int x,int f){ fa[x]=f; d[x]=d[f]+1; siz[x]=1; int maxson=-1; for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y==f) continue; w[y]=edge[i]; dfs1(y,x); siz[x]+=siz[y]; if(maxson<siz[y]) maxson=siz[y],son[x]=y; } } void dfs2(int x,int t){ top[x]=t; dfn[x]=++cnt; rnk[cnt]=x; if(!son[x]) return; dfs2(son[x],t); for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y!=fa[x]&&y!=son[x]) dfs2(y,y); } } void UPD1(int x,int y,int val){ while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); updsame(1,dfn[top[x]],dfn[x],val); x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); updsame(1,dfn[x]+1,dfn[y],val); } void UPD2(int x,int y,int val){ while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); updadd(1,dfn[top[x]],dfn[x],val); x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); updadd(1,dfn[x]+1,dfn[y],val); } int qMax(int x,int y){ int ans=-1; while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); ans=max(ans,query(1,dfn[top[x]],dfn[x])); x=fa[top[x]]; } if(d[x]>d[y]) swap(x,y); ans=max(ans,query(1,dfn[x]+1,dfn[y])); return ans; } int main(){ int n; //freopen("lxh.in","r",stdin); //freopen("lxh.out","w",stdout); cin>>n; for(int i=1;i<=n-1;i++){ int x,y,z; cin>>x>>y>>z; addedge(x,y,z); addedge(y,x,z); u[i]=x,v[i]=y; } dfs1(1,0); dfs2(1,1); build(1,1,n); while(1){ string op; int x,y,val; cin>>op; if(op=="Stop") break; else if(op=="Max"){ cin>>x>>y; cout<<qMax(x,y)<<endl; } else if(op=="Cover"){ cin>>x>>y>>val; UPD1(x,y,val); } else if(op=="Add"){ cin>>x>>y>>val; UPD2(x,y,val); } else{ int i; cin>>i>>val; int x=u[i],y=v[i]; if(fa[y]==x) updsame(1,dfn[y],dfn[y],val); else updsame(1,dfn[x],dfn[x],val); } } return 0; } P4427 [BJOI2018]求和 #include<bits/stdc++.h> const int N=3e5+100; #define inf 0x3f3f3f3f #define ll long long #define p 998244353 using namespace std; int n,m,cnt; int d[N],son[N],s[N][51],siz[N]; int top[N],fa[N]; int head[N],edge[N<<1],ver[N<<1],nex[N<<1]; int tot=0; void addedge(int x,int y,int z){ ver[++tot]=y,nex[tot]=head[x]; edge[tot]=z;head[x]=tot; } inline int power(int a,int t){ int res = 1; while(t){ if(t&1) res = (ll)res*a%p; a = (ll)a*a%p; t >>= 1; } return res; } inline void read(int &x){ x = 0; char c = getchar(); while(!isdigit(c)) c = getchar(); while(isdigit(c)){ x = (x<<3)+(x<<1)+c-'0'; c = getchar(); } } void print(int x){ if(x>9) print(x/10); putchar(x%10+'0'); } void dfs1(int x,int f){ fa[x]=f; d[x]=d[f]+1; siz[x]=1; ll maxson=-1; for(int i=0;i<=50;i++){ s[x][i]=(s[f][i]+power(d[x]-1,i))%p; } for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y==f) continue; dfs1(y,x); siz[x]+=siz[y]; if(maxson<siz[y]) maxson=siz[y],son[x]=y; } } void dfs2(int x,int t){ top[x]=t; if(!son[x]) return; dfs2(son[x],t); for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y!=fa[x]&&y!=son[x]) dfs2(y,y); } } inline int lca(int u,int v){ int t; while(top[u]!=top[v]){ if(d[top[u]]<d[top[v]]){ t = u; u = v; v = t; } u = fa[top[u]]; } if(d[u]<d[v]) return u; return v; } int main(){ int u,v,k,f,ans; read(n); for(int i=1;i<n;++i){ read(u),read(v); addedge(u,v,1); addedge(v,u,1); } dfs1(1,0); dfs2(1,1); read(m); ++m; while(--m){ read(u),read(v),read(k); f = lca(u,v); ans = (s[u][k]+s[v][k])%p; ans -= (s[f][k]+s[fa[f]][k])%p; ans = (ans+p)%p; print(ans); putchar(10); } return 0; }
最新回复(0)