一个一个删,树剖线段树上维护即可。
#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define mid (l+r>>1)
#define inf (ll)2e18
#define N 100009
#define root 1,1,n
#define lc cur<<1
#define rc lc|1
#define lson lc,l,mid
#define rson rc,mid+1,r
#define now cur,l,r
using namespace std;
ll n,m,Q,first[N],number,fa[N],size[N],top[N],deep[N],Mson[N],dfn[N],id[N],ed[N],cnt;
ll tg[N<<2],print[N],pos[N];
struct edge
{
ll to,next;
void add(ll x,ll y)
{
to=y,next=first[x],first[x]=number;
}
}e[N<<1];
struct node
{
ll pos,val,id;
node(ll pos=0,ll val=0,ll id=0):pos(pos),val(val),id(id){}
bool operator <(const node &rhs) const
{
return val<rhs.val||(val==rhs.val&&pos<rhs.pos);
}
}Min[N<<2];
vector<node> a[N];
ll read()
{
ll x=1;
char ch;
while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;
ll s=ch-'0';
while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';
return s*x;
}
void dfs1(ll x)
{
deep[x]=deep[fa[x]]+1;
size[x]=1;
for (ll i=first[x];i;i=e[i].next)
if (e[i].to!=fa[x])
{
fa[e[i].to]=x;
dfs1(e[i].to);
size[x]+=size[e[i].to];
if (size[e[i].to]>size[Mson[x]]) Mson[x]=e[i].to;
}
}
void dfs2(ll x,ll y)
{
top[x]=y;
id[dfn[x]=++cnt]=x;
if (Mson[x]) dfs2(Mson[x],y);
for (ll i=first[x];i;i=e[i].next)
if (e[i].to!=fa[x]&&e[i].to!=Mson[x]) dfs2(e[i].to,e[i].to);
ed[x]=cnt;
}
void down(ll cur,ll l,ll r)
{
if (tg[cur]>0)
{
tg[lc]+=tg[cur];
tg[rc]+=tg[cur];
Min[lc].val+=tg[cur];
Min[rc].val+=tg[cur];
tg[cur]=0;
}
}
void up(ll cur,ll l,ll r)
{
Min[cur]=min(Min[lc],Min[rc]);
}
void build(ll cur,ll l,ll r)
{
tg[cur]=0;
if (l==r)
{
Min[cur]=(a[id[l]].size()!=0?a[id[l]][0]:node(0,inf,inf));
return;
}
build(lson);
build(rson);
up(now);
}
void ins(ll cur,ll l,ll r,ll L,ll R,ll x)
{
if (L<=l&&R>=r)
{
tg[cur]+=x;
Min[cur].val+=x;
return;
}
down(now);
if (L<=mid) ins(lson,L,R,x);
if (R>mid) ins(rson,L,R,x);
up(now);
}
ll get_tg(ll cur,ll l,ll r,ll x)
{
if (l==r) return tg[cur];
if (x<=mid) return tg[cur]+get_tg(lson,x);
else return tg[cur]+get_tg(rson,x);
}
void del(ll cur,ll l,ll r,ll x)
{
if (l==r)
{
pos[id[l]]++;
Min[cur]=(a[id[l]].size()>pos[id[l]]?a[id[l]][pos[id[l]]]:node(0,inf,inf));
if (a[id[l]].size()>pos[id[l]]) Min[cur].val+=get_tg(root,l);
return;
}
down(now);
if (x<=mid) del(lson,x);
else del(rson,x);
up(now);
}
node qry(ll cur,ll l,ll r,ll L,ll R)
{
if (L<=l&&R>=r) return Min[cur];
down(now);
node ret=node(0,inf,inf);
if (L<=mid) ret=min(ret,qry(lson,L,R));
if (R>mid) ret=min(ret,qry(rson,L,R));
return ret;
}
node qry(ll x,ll y)
{
node ret=node(0,inf,inf);
for (;top[x]!=top[y];x=fa[top[x]])
{
if (deep[top[x]]<deep[top[y]]) swap(x,y);
ret=min(ret,qry(root,dfn[top[x]],dfn[x]));
}
if (dfn[x]>dfn[y]) swap(x,y);
return min(ret,qry(root,dfn[x],dfn[y]));
}
int main()
{
n=read(),m=read(),Q=read();
//n=1,m=100000,Q=100000;
for (ll i=1;i<n;i++)
{
ll x=read(),y=read();
e[++number].add(x,y),e[++number].add(y,x);
}
for (ll i=1;i<=m;i++)
{
ll x=read();
//ll x=1;
a[x].push_back(node(x,i,i));
}
for (ll i=1;i<=n;i++) pos[i]=0,sort(a[i].begin(),a[i].end());
dfs1(1);
dfs2(1,1);
build(root);
while (Q--)
{
ll op=read();
//ll op=1;
if (op==1)
{
ll x=read(),y=read(),k=read(),num=0;
//ll x=1,y=1,k=1,num=0;
for (num=0;num<k;num++)
{
node Now=qry(x,y);
if (Now.pos==0) break;
else
{
print[num+1]=Now.id;
del(root,dfn[Now.pos]);
}
}
printf("%lld",num);
for (ll i=1;i<=num;i++) printf(" %lld",print[i]);
puts("");
}
else
{
ll x=read(),k=read();
ins(root,dfn[x],ed[x],k);
}
}
return 0;
}