感觉今天浪费了好多时间写水题...
主要传达的思想是换跟操作不一定要真的换,查询的时候讨论一下查询点与目前根的关系即可.
1 //Achen
2 #include<algorithm>
3 #include<iostream>
4 #include<cstring>
5 #include<cstdlib>
6 #include<cstdio>
7 #include<cmath>
8 #include<queue>
9 #include<set>
10 #include<map>
11 #define inf 0x7fffffff
12 #define For(i,a,b) for(int i=(a);i<=(b);i++)
13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
14 const int N=2e5+7;
15 typedef long long LL;
16 typedef double db;
17 using namespace std;
18 int n,m,rt,RT;
19 LL v[N];
20
21 template<typename T>void read(T &x) {
22 char ch=getchar(); x=0; T f=1;
23 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
24 if(ch=='-') f=-1,ch=getchar();
25 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
26 }
27
28 LL sg[N<<2],lz[N<<2];
29 #define lc x<<1
30 #define rc ((x<<1)|1)
31 #define mid ((l+r)>>1)
32 void down(int x,int l_len,int r_len) {
33 if(!lz[x]) return;
34 if(l_len) sg[lc]=lz[x],lz[lc]=lz[x];
35 if(r_len) sg[rc]=lz[x],lz[rc]=lz[x];
36 lz[x]=0;
37 }
38
39 void update(int x,int l,int r,int ql,int qr,int v) {
40 if(l>=ql&&r<=qr) {
41 sg[x]=v; lz[x]=v; return;
42 }
43 down(x,mid-l+1,r-mid);
44 if(ql<=mid) update(lc,l,mid,ql,qr,v);
45 if(qr>mid) update(rc,mid+1,r,ql,qr,v);
46 sg[x]=min(sg[lc],sg[rc]);
47 }
48
49 LL qry(int x,int l,int r,int ql,int qr) {
50 if(ql>qr) return inf;
51 if(l>=ql&&r<=qr) return sg[x];
52 down(x,mid-l+1,r-mid);
53 if(qr<=mid) return qry(lc,l,mid,ql,qr);
54 if(ql>mid) return qry(rc,mid+1,r,ql,qr);
55 return min(qry(lc,l,mid,ql,qr),qry(rc,mid+1,r,ql,qr));
56 }
57
58 int ecnt,fir[N],nxt[N<<1],to[N<<1];
59 void add(int u,int v) {
60 nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
61 nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u;
62 }
63
64 int fa[N],R[N],sz[N],dfn[N],tid[N],top[N],dfs_clock;
65 void dfs(int x,int Fa) {
66 sz[x]=1;
67 fa[x]=Fa;
68 R[x]=R[Fa]+1;
69 for(int i=fir[x];i;i=nxt[i]) if(to[i]!=Fa) {
70 dfs(to[i],x);
71 sz[x]+=sz[to[i]];
72 }
73 }
74
75 void dfs2(int x,int Top) {
76 tid[++dfs_clock]=x;
77 dfn[x]=dfs_clock;
78 update(1,1,n,dfs_clock,dfs_clock,v[x]);
79 top[x]=Top;
80 int mson=0;
81 for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa[x]) {
82 if(!mson||sz[mson]<sz[to[i]]) mson=to[i];
83 }
84 if(mson) dfs2(mson,Top);
85 for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa[x]&&to[i]!=mson) {
86 dfs2(to[i],to[i]);
87 }
88 }
89
90 void schange(int x,int y,int v) {
91 while(top[x]!=top[y]) {
92 if(R[top[x]]<R[top[y]]) swap(x,y);
93 update(1,1,n,dfn[top[x]],dfn[x],v);
94 x=fa[top[x]];
95 }
96 if(dfn[x]>dfn[y]) swap(x,y);
97 update(1,1,n,dfn[x],dfn[y],v);
98 }
99
100 //#define DEBUG
101 int main() {
102 #ifdef DEBUG
103 freopen("std.in","r",stdin);
104 #endif
105 read(n); read(m);
106 For(i,2,n) {
107 int x,y;
108 read(x); read(y);
109 add(x,y);
110 }
111 For(i,1,n) read(v[i]);
112 read(rt); RT=rt;
113 dfs(rt,0);
114 dfs2(rt,rt);
115 For(ti,1,m) {
116 int o,x,y; LL v;
117 read(o);
118 if(o==1) read(rt);
119 else if(o==2) {
120 read(x); read(y); read(v);
121 schange(x,y,v);
122 }
123 else {
124 read(x); LL ans;
125 if(x==rt) ans=sg[1];
126 else if(dfn[rt]>dfn[x]&&dfn[rt]<dfn[x]+sz[x]) {
127 int y=0;
128 for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa[x]) {
129 y=to[i];
130 if(dfn[rt]>=dfn[y]&&dfn[rt]<dfn[y]+sz[y]) break;
131 }
132 ans=min(qry(1,1,n,1,dfn[y]-1),qry(1,1,n,dfn[y]+sz[y],n));
133 }
134 else ans=qry(1,1,n,dfn[x],dfn[x]+sz[x]-1);
135 printf("%lld
",ans);
136 }
137 }
138 return 0;
139 }
//Achen #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<vector> #include<cstdio> #include<queue> #include<cmath> #include<ctime> #include<set> #define For(i,a,b) for(int i=(a);i<=(b);i++) #define Rep(i,a,b) for(int i=(a);i>=(b);i--) typedef long long LL; typedef double db; int vis[1000007],fa[100007],cnt[100008][11],ok[5007][5007]; using namespace std; int find(int x) { return x==fa[x]?x:find(fa[x]); } //#define DEBUG int main() { #ifdef DEBUG //freopen("line.in","r",stdin); freopen("std.in","w",stdout); #endif srand(time(0)); int n=50,m=50; printf("%d %d ",n,m); For(i,2,n) { int fa=rand()%(i-1)+1; printf("%d %d ",fa,i); } For(i,1,n) { int x=rand()%100+1; printf("%d ",x); } puts(""); int rt=rand()%n+1; printf("%d ",rt); For(i,1,m) { int o,x,y; o=rand()%3; if(o==0) { x=rand()%n+1; printf("%d %d ",o+1,x); } else if(o==1) { x=rand()%n+1,y=rand()%n+1; int v=rand()%100+1; printf("%d %d %d %d ",o+1,x,y,v); } else { x=rand()%n+1; printf("%d %d ",o+1,x); } } return 0; }