#include <bits/stdc++.h>
#define ll long long
#define KG putchar(' ')
using namespace std;
#define N (int)(2e5+5)
#define inf (ll)(2e18)
#define min(A,B) (A<B?A:B)
queue<int>q[N];
struct DAT {
ll x; int id,pos;
DAT(ll xx=inf,int idd=(int)(1e9),int poss=0) {
x=xx; id=idd; pos=poss;
}
bool operator < (const DAT &rhs) const {
return x==rhs.x?id<rhs.id:x<rhs.x;
}
};
struct edge {
int nex,to;
}e[N<<1];
int tot,rk[N],id[N],tp[N],fa[N],dep[N],sz[N],son[N];
int hea[N],cnt;
int n,m,Q;
namespace xgf {
#define ls (cur<<1)
#define rs (ls|1)
struct TREE {
DAT mi;
ll tag;
TREE(DAT mii=DAT(inf,(int)(1e9),0),ll tagg=0) {
mi=mii; tag=tagg;
}
}T[N<<2];
void push_up(int cur) {
T[cur].mi=min(DAT(T[ls].mi.x,T[ls].mi.id,T[ls].mi.pos),DAT(T[rs].mi.x,T[rs].mi.id,T[rs].mi.pos));
}
void push_down(int cur) {
if(!T[cur].tag) return ;
T[ls].tag+=T[cur].tag; T[rs].tag+=T[cur].tag;
T[ls].mi.x+=T[cur].tag; T[rs].mi.x+=T[cur].tag;
T[cur].tag=0;
}
void build(int cur,int l,int r) {
if(l==r) {
if(q[rk[l]].empty()) T[cur].mi=DAT(inf,(int)(1e9),0);
else {
T[cur].mi=DAT(q[rk[l]].front(),q[rk[l]].front(),l);
}
return ;
}
int mid=(l+r)>>1;
build(ls,l,mid); build(rs,mid+1,r);
push_up(cur);
}
void update(int cur,int l,int r,int cl,int cr,ll x) {
if(cl<=l&&r<=cr) {
T[cur].tag+=x; T[cur].mi.x+=x; return ;
}
push_down(cur);
int mid=(l+r)>>1;
if(cl<=mid) update(ls,l,mid,cl,cr,x);
if(cr>mid) update(rs,mid+1,r,cl,cr,x);
push_up(cur);
}
DAT query(int cur,int l,int r,int cl,int cr) {
if(cl<=l&&r<=cr) {
return DAT(T[cur].mi.x,T[cur].mi.id,T[cur].mi.pos);
}
push_down(cur);
int mid=(l+r)>>1;
if(cr<=mid) return query(ls,l,mid,cl,cr);
if(cl>mid) return query(rs,mid+1,r,cl,cr);
return min(query(ls,l,mid,cl,cr),query(rs,mid+1,r,cl,cr));
push_up(cur);
}
void del(int cur,int l,int r,int pos) {
if(l==r) {
ll qwq=q[rk[l]].front(); q[rk[l]].pop();
if(q[rk[l]].empty()) T[cur].mi=DAT(inf,(int)(1e9),0);
else {
qwq=T[cur].mi.x-qwq+q[rk[l]].front();
T[cur].mi=DAT(qwq,q[rk[l]].front(),l);
}
return ;
}
push_down(cur);
int mid=(l+r)>>1;
if(pos<=mid) del(ls,l,mid,pos);
else del(rs,mid+1,r,pos);
push_up(cur);
}
}
void add_edge(int x,int y) {
e[++cnt].nex=hea[x]; e[cnt].to=y; hea[x]=cnt;
}
void dfs1(int x,int ff) {
fa[x]=ff; dep[x]=dep[ff]+1; sz[x]=1;
for(int i=hea[x];i;i=e[i].nex) {
int y=e[i].to; if(y==ff) continue;
dfs1(y,x); sz[x]+=sz[y];
if(sz[y]>sz[son[x]]) son[x]=y;
}
}
void dfs2(int x,int tpp) {
tp[x]=tpp; id[x]=++tot; rk[tot]=x;
if(son[x]) dfs2(son[x],tpp);
for(int i=hea[x];i;i=e[i].nex) {
int y=e[i].to;
if(y==son[x]||y==fa[x]) continue;
dfs2(y,y);
}
}
vector<int>ans;
void solve(int fx,int fy,int z) {
ans.clear();
while(z--) {
int x=fx,y=fy; DAT res=DAT(inf,(int)(1e9),0);
while(tp[x]!=tp[y]) {
if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
res=min(res,xgf::query(1,1,n,id[tp[x]],id[x]));
x=fa[tp[x]];
}
if(id[x]>id[y]) swap(x,y);
res=min(res,xgf::query(1,1,n,id[x],id[y]));
if(res.x>=inf) break;
ans.push_back(res.id);
xgf::del(1,1,n,res.pos);
}
cout<<ans.size()<<" ";
for(int i=0;i<ans.size();i++) cout<<ans[i]<<" ";
cout<<"\n";
}
signed main() {
ios::sync_with_stdio(false);
cout.tie(NULL);
int op,x,y,z;
cin>>n>>m>>Q;
for(int i=1;i<n;i++) {
cin>>x>>y;
add_edge(x,y); add_edge(y,x);
}
for(int i=1;i<=m;i++) {
cin>>x;
q[x].push(i);
}
dfs1(1,0); dfs2(1,0); xgf::build(1,1,n);
while(Q--) {
cin>>op>>x>>y;
if(op==1) {
cin>>z;
solve(x,y,z);
} else {
xgf::update(1,1,n,id[x],id[x]+sz[x]-1,1ll*y);
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】