(抱歉刚刚发错了)
怎么算这空间都不会炸呀,卡了一面了。
#include <cstdio>
#include <iostream>
#include <algorithm>
#define u64 long long
#define pii pair<int, int>
using namespace std;
const int maxn = 1e6 + 1e2;
const int maxm = 3e5 + 1e2;
const int maxq = 5e5 + 1e2;
const int inf = 1e9 + 10e1;
#define fin cin
#define fout cout
#define Endl '\n'
int n, m, q, p[maxn], u[maxm], v[maxm];
int k[maxq]; bool t[maxq], vis[maxm];
inline read()
{
fin >> n >> m >> q; int tmp;
for (int i = 1; i <= n; i++) fin >> p[i];
for (int i = 1; i <= m; i++) fin >> u[i] >> v[i];
for (int i = 1; i <= q; i++) fin >> tmp >> k[i], t[i] = tmp - 1;
for (int i = 1; i <= q; i++) t[i] && (vis[k[i]] = true);
}
namespace Tree
{
struct Edge { int to, nx; };
Edge G[maxn + maxm];
int hd[maxn + maxm], tot;
int vl[maxn + maxm], cnt;
addEdge(int x, int y)
{
++tot;
G[tot].to = y;
G[tot].nx = hd[x];
hd[x] = tot;
}
link(int x, int y)
{
addEdge(x, y); addEdge(y, x);
}
int newnode(int val)
{
vl[++cnt] = val; return cnt;
}
int /*g[maxn][20], */dfn[maxn], pnt[maxn], sze[maxn], ncl;
dfs(int x, int fa)
{
sze[x] = 1;
//g[x][0] = fa;
dfn[x] = ++ncl;
pnt[ncl] = x > n ? 0 : x;
/*for (int i = 1; i < 20; i++)
{
g[x][i] = g[g[x][i - 1]][i - 1];
}*/
for (int i = hd[x]; i; i = G[i].nx)
{
int s = G[i].to;
if (s == fa) continue;
dfs(s, x); sze[x] += sze[s];
}
}
/*
inline int get(int x, int w)
{
for (int i = 19; i >= 0; i--)
{
if (vl[g[x][i]] > w)
{
x = g[x][i];
}
}
return x;
}*/
}
using namespace Tree;
namespace Set
{
int fa[maxn * 4], num;
inline init(int n)
{
for (int i = 1; i <= 4 * n; i++)
{
fa[i] = i;
}
}
int find(int x)
{
if (fa[x] == x) return x;
return fa[x] = find(fa[x]);
}
inline merge(int x, int y)
{
++num;
fa[find(x)] = num;
fa[find(y)] = num;
}
};
using namespace Set;
namespace SegmentTree
{
int /*mxvl[maxn * 4], */mxps[maxn * 4];
pushup(int x)
{
if (p[pnt[mxps[x << 1]]] > p[pnt[mxps[x << 1 | 1]]])
{
//mxvl[x] = mxvl[x << 1];
mxps[x] = mxps[x << 1];
}
else
{
//mxvl[x] = mxvl[x << 1 | 1];
mxps[x] = mxps[x << 1 | 1];
}
}
void build(int x, int l, int r)
{
if (l == r)
{
mxps[x] = l;
//mxvl[x] = p[pnt[l]];
//cout << x << " " << l <<" " <<dfn[l] << " " <<p[dfn[l]] <<endl;
return;
}
int mid = (l + r) >> 1;
build(x << 1, l, mid);
build(x << 1 | 1, mid + 1, r);
pushup(x);
}
void update(int x, int l, int r, int pos, int k)
{
if (!r) return;
if (l == r)
{
p[pnt[l]] = k; return;
}
int mid = (l + r) >> 1;
if (pos <= mid)
update(x << 1, l, mid, pos, k);
else
update(x << 1 | 1, mid + 1, r, pos, k);
pushup(x);
}
int query(int x, int l, int r, int ll, int rr)
{//cout << "xxx" << " " << l << " " <<r <<" " << ll <<" " << rr << Endl;
//if (ll > r || rr < l || l > r)
//if (!r) return make_pair(-inf, 0);
//if (l > n) return make_pair(-inf, 0);
if (ll <= l && r <= rr)
{
return mxps[x];
}
int mid = (l + r) >> 1, res = 0;
//pii res = make_pair(-inf, 0);
if (ll <= mid)
{
//res = max(res, );
int tmp = query(x << 1, l, mid, ll, rr);
if (p[pnt[tmp]] > p[pnt[res]]) res = tmp;
}
if (rr > mid)
{
//res = max(res, query(x << 1 | 1, mid + 1, r, ll, rr));
int tmp = query(x << 1 | 1, mid + 1, r, ll, rr);
if (p[pnt[tmp]] > p[pnt[res]]) res = tmp;
}
/*return max(query(x << 1, l, mid, ll, rr),
query(x << 1 | 1, mid + 1, r, ll, rr));*/
return res;
}
};
using namespace SegmentTree;
int get_[maxn * 3];
prework()
{
init(n);
num = cnt = n;
for (int i = 1; i <= m; i++)
{
if (!vis[i])
{
int fa = newnode(q + 1);
//cout << "#" << find(u[i]) << " ";
//cout << "#" << find(v[i]) << endl;
link(find(u[i]), fa);
link(find(v[i]), fa);
merge(u[i], v[i]);
}
}
for (int i = q; i; i--)
{
get_[i] = find(k[i]);
if (!t[i]) continue;
//cout << u[k[i]] <<" " <<v[k[i]] << endl;
if (find(u[k[i]]) != find(v[k[i]]))
{
int fa = newnode(i);
//cout << "#" << find(u[k[i]]) << " ";
//cout << "#" << find(v[k[i]]) << endl;
link(find(u[k[i]]), fa);
link(find(v[k[i]]), fa);
merge(u[k[i]], v[k[i]]);
}
}
delete u; delete v; delete vis;
//dfs(cnt, 0);
for (int i = 1; i <= cnt; i++)
{
if (find(i) == i) /*cout <<"$"<<i <<endl,*/dfs(i, 0);
}
delete fa; delete G; //delete vl;
build(1, 1, cnt);
}
solve()
{//cout << ncl << endl;
for (int i = 1; i <= q; i++)
{
if (t[i]) continue;
//int w = get(k[i], i); //cout << dfn[k[i]] <<" "<< w << " ";
int w = get_[i];
//cout << dfn[w] << " " << dfn[w] + sze[w] - 1 << endl;
int x = query(1, 1, cnt, dfn[w], dfn[w] + sze[w] - 1);
//cout << "ans: "<< x.first << " " <<x.second <<Endl;
fout << p[pnt[x]] << Endl;
update(1, 1, cnt, x, 0);
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
read();
prework();
solve();
//fwrite(obuf, O_ - obuf, 1, stdout);
return 0;
}