rt,测了下样例提示 *** stack smashing detected ***: terminated
//when you use vector or deque,pay attention to the size of it.
//by OldDirverTree
#include<bits/stdc++.h>
#include<bits/extc++.h>
//#include<atcoder/all>
#define P pair<int,int>
#define int long long
#define mid (l+r>>1)
using namespace std;
using namespace __gnu_pbds;
//using namespace atcoder;
const int N=1e5+1,M=2e5,V=1e9;
struct node { int ls,rs,cnt,sum; }T[N*50];
int tot,tim,root[N],dfn[N],low[N],bel[N];
struct change { int o,x,y; }C[M];
struct edge { int x,y,t; }e[M];
stack<int> s; bool ins[N];
vector<int> a,ans,g[N];
int n,m,q,w[N],fa[N];
map<P,int> tax;
int read() {
int x=0; bool f=true; char c=0;
while (!isdigit(c) ) f&=(c!='-'),c=getchar();
while (isdigit(c) ) x=(x<<3)+(x<<1)+(c&15),c=getchar();
return f?x:-x;
}
void tarjan(int u) {
dfn[u]=low[u]=++tim,s.push(u),ins[u]=true; for (int v:g[u])
if (!dfn[v]) tarjan(v),low[u]=min(low[u],low[v]); else if (ins[v]) low[u]=min(low[u],dfn[v]);
if (dfn[u]==low[u]) for (int o=0;o^u;o=s.top(),s.pop(),ins[o]=false,bel[o]=u);
}
void solve(int l,int r,int L,int R)
{
if (l==r||L>R) return; int pos=R;
for (int i=R;i>=L;i--) if (e[i].t>mid) swap(e[i],e[pos--]);
for (int x:a) dfn[x]=low[x]=bel[x]=0,g[x].clear(); a.clear(),tim=0;
for (int i=L;i<=pos;i++) g[e[i].x].push_back(e[i].y),a.push_back(e[i].x),a.push_back(e[i].y);
for (int x:a) if (!dfn[x]) tarjan(x);
for (int i=pos;i>=L;i--) if (bel[e[i].x]^bel[e[i].y]||!bel[e[i].x]) e[i].t=mid+1,swap(e[i],e[pos--]);
for (int i=pos+1;i<=R;i++) {
if (bel[e[i].x]) e[i].x=bel[e[i].x];
if (bel[e[i].y]) e[i].y=bel[e[i].y];
}
solve(l,mid,L,pos);
solve(mid+1,r,pos+1,R);
}
int find(int x) {
return fa[x]^x?fa[x]=find(fa[x]):x;
}
void update(int &rt,int l,int r,int x,int y) {
if (!rt) rt=++tot; T[rt].cnt+=y,T[rt].sum+=x*y; if (l==r) return;
x<=mid?update(T[rt].ls,l,mid,x,y):update(T[rt].rs,mid+1,r,x,y);
}
int query(int rt,int l,int r,int k) {
printf("%lld %lld %lld %lld %lld %lld\n",rt,l,r,k,T[rt].cnt,T[rt].sum);
if (T[rt].cnt<=k) return T[rt].sum; if (l==r) return k*l;
if (T[T[rt].rs].cnt>=k) return query(T[rt].rs,mid+1,r,k);
else T[T[rt].rs].sum+query(T[rt].ls,l,mid,k-T[T[rt].rs].cnt);
}
void merge(int &x,int y) {
if (!x||!y) return x|=y,void();
T[x].cnt+=T[y].cnt,T[x].sum+=T[y].sum;
merge(T[x].ls,T[y].ls),merge(T[x].rs,T[y].rs);
}
main()
{
n=read(),m=read(),q=read();
for (int i=1;i<=n;i++) w[i]=read();
for (int i=1;i<=m;i++) e[i]={read(),read(),0},tax[{e[i].x,e[i].y}]=i;
for (int i=q;i;i--) {
C[i]={read(),read(),read()};
if (C[i].o==1) e[tax[{C[i].x,C[i].y}] ].t=i;
else if (C[i].o==2) w[C[i].x]+=C[i].y;
}
for (int i=1;i<=n;i++) update(root[i],1,V,w[i],1);
solve(0,q,1,m); for (int i=1;i<=n;i++) fa[i]=i;
for (int i=0,pos=1;i<=q;i++) {
while (pos<=m&&e[pos].t==i) { int x=find(e[pos].x),y=find(e[pos].y); pos++; if (x^y) fa[y]=x,merge(root[x],root[y]); }
if (C[i].o==2) update(root[find(C[i].x)],1,V,w[C[i].x],-1),update(root[find(C[i].x)],1,V,w[C[i].x]-=C[i].y,1);
if (C[i].o==3) ans.push_back(query(root[find(C[i].x)],1,V,C[i].y) );
}
reverse(ans.begin(),ans.end() );
for (int x:ans) printf("%lld\n",x);
return 0;
}