操作3调了一年,想打人
早知道就用倍增了
树剖求子树太麻烦了
不说了,晚上月考赶紧去复习
#include <bits/stdc++.h>
#define il inline
#define Max 1000005
#define rg register
#define int long long
#define ls(x) x<<1
#define rs(x) x<<1|1
#define dg puts("qwq")
#define getchar() (tt==ss&&(tt=(ss=In)+fread(In,1,Max,stdin),tt==ss)?EOF:*ss++)
using namespace std;
char In[Max],*ss=In,*tt=In;
il int read()
{
char c=getchar();
int x=0;
while(c>'9'||c<'0')
{
c=getchar();
}
while(c>='0'&&c<='9')
{
x=x*10+c-'0';
c=getchar();
}
return x;
}
struct node
{
int t,nt;
}e[Max<<1];
int head[Max],tot,cnt,t[Max<<2],tg[Max<<2],dfn[Max],tp[Max],wsn[Max],n,m,rt,w[Max],f[Max],rk[Max],sz[Max],d[Max];
il void add(int u,int v)
{
e[++tot].t=v;
e[tot].nt=head[u];
head[u]=tot;
}
il void dfs1(int u,int fa)
{
d[u]=d[fa]+1;sz[u]=1;f[u]=fa;
for(int i=head[u];i;i=e[i].nt)
{
int v=e[i].t;
if(v==fa) continue;
dfs1(v,u);
sz[u]+=sz[v];
if(sz[v]>sz[wsn[u]]) wsn[u]=v;
}
}
il void dfs2(int u,int top)
{
tp[u]=top;
dfn[u]=++cnt;
rk[cnt]=u;
if(wsn[u]) dfs2(wsn[u],top);
for(int i=head[u];i;i=e[i].nt)
{
int v=e[i].t;
if(v==f[u]||v==wsn[u]) continue;
dfs2(v,v);
}
}
il int Lca(int x,int y)
{
while(tp[x]!=tp[y])
{
if(d[tp[x]]<d[tp[y]]) swap(x,y);
x=f[tp[x]];
}
return d[x]<d[y]?x:y;
}
il void pushup(int x)
{
t[x]=min(t[ls(x)],t[rs(x)]);
}
il void pushdown(int x)
{
if(tg[x]==-1) return;
tg[ls(x)]=t[ls(x)]=tg[x];
tg[rs(x)]=t[rs(x)]=tg[x];
tg[x]=-1;
}
il void build(int x,int l,int r)
{
tg[x]=-1;
if(l==r)
{
t[x]=w[rk[l]];
return;
}
int mid=(l+r)>>1;
build(ls(x),l,mid);
build(rs(x),mid+1,r);
pushup(x);
}
il void mdf(int x,int l,int r,int ql,int qr,int k)
{
if(ql<=l&&r<=qr)
{
tg[x]=t[x]=k;
return;
}
int mid=(l+r)>>1;
pushdown(x);
if(ql<=mid) mdf(ls(x),l,mid,ql,qr,k);
if(qr>mid) mdf(rs(x),mid+1,r,ql,qr,k);
pushup(x);
}
il int qry(int x,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr)
{
return t[x];
}
pushdown(x);
int mid=(l+r)>>1;
int res=1e17;
if(ql<=mid) res=min(res,qry(ls(x),l,mid,ql,qr));
if(qr>mid) res=min(res,qry(rs(x),mid+1,r,ql,qr));
pushup(x);
return res;
}
il void modify(int x,int y,int w)
{
while(tp[x]!=tp[y])
{
if(d[tp[x]]<d[tp[y]]) swap(x,y);
mdf(1,1,n,dfn[tp[x]],dfn[x],w);
x=f[tp[x]];
}
if(dfn[x]>dfn[y]) swap(x,y);
mdf(1,1,n,dfn[x],dfn[y],w);
}
il int find(int u)
{
if(u==rt) return -1;
if(dfn[u]>=dfn[rt]||dfn[u]+sz[u]-1<dfn[rt]) return 0;
int v=rt;
while(tp[u]!=tp[v])
{
if(f[tp[v]]==u) return tp[v];
v=f[tp[v]];
}
return wsn[u];
}
il int work(int u)
{
int v=find(u);
if(v==-1) return t[1];
if(v==0) return qry(1,1,n,dfn[u],dfn[u]+sz[u]-1);
else
{
int ans=qry(1,1,n,1,dfn[v]-1);
if(dfn[v]+sz[v]-1!=n) ans=min(ans,qry(1,1,n,dfn[v]+sz[v],n));
return ans;
}
}
signed main()
{
sz[0]=-1;
n=read(),m=read();
for(int i=1;i<n;i++)
{
int u=read(),v=read();
add(u,v),add(v,u);
}
for(int i=1;i<=n;i++) w[i]=read();
rt=read();
dfs1(rt,1);
dfs2(rt,rt);
build(1,1,n);
while(m--)
{
int opt=read();
if(opt==1)
{
rt=read();
}
else if(opt==2)
{
int u=read(),v=read(),w=read();
modify(u,v,w);
}
else if(opt==3)
{
int u=read();
printf("%lld\n",work(u));
}
}
}
最后一次更新于2021-09-28 02:20:06
0 条评论