rt,第 3 个点过不去
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
inline int read()
{
int x = 0; char c = getchar();
while(c < '0' || c > '9') c = getchar();
while(c >= '0' && c <= '9')
x = (x<<3)+(x<<1)+c-'0', c = getchar();
return x;
}
const int MAXN = 200010;
const int MAXM = 150010;
const int MAXA = 1000010;
//const int N = 1000000;
int n, m, q, totn;
int dfn[MAXN], cnt, siz[MAXN], rev[MAXN];
struct Tree{
struct edge{
int ne, to;
edge(int Ne=0,int To=0):ne(Ne),to(To){}
}e[MAXN];
int fir[MAXN], num;
inline void reset()
{
for(int i=1;i<=(n<<1);i++)
fir[i] = dfn[i] = 0;
num = cnt = 0;
}
inline void join(int a, int b)
{
e[++num] = edge(fir[a], b);
fir[a] = num;
}
void dfs(int u)
{
dfn[u] = ++cnt;
rev[cnt] = u;
siz[u] = 1;
for(int i=fir[u];i;i=e[i].ne)
{
int v = e[i].to;
dfs(v);
siz[u] += siz[v];
}
}
}T;
struct Graph{
struct edge{
int ne, to;
edge(int Ne=0,int To=0):ne(Ne),to(To){}
}e[MAXM<<1];
int fir[MAXN], num, dfn[MAXN], cnt, low[MAXN], stk[MAXN], top;
inline void reset()
{
for(int i=1;i<=(n<<1);i++)
fir[i] = dfn[i] = 0;
top = num = cnt = 0;
}
inline void join(int a, int b)
{
e[++num] = edge(fir[a], b);
fir[a] = num;
}
void tarjan(int u)
{
dfn[u] = low[u] = ++cnt;
stk[++top] = u;
for(int i=fir[u];i;i=e[i].ne)
{
int v = e[i].to;
if(!dfn[v])
{
tarjan(v);
low[u] = min(low[u], low[v]);
if(low[v] >= dfn[u])
{
int x = 0; ++totn;
T.join(u, totn);
do {
x = stk[top--];
T.join(totn, x);
} while(x != v);
}
}
else low[u] = min(low[u], dfn[v]);
}
}
}G;
struct blocks{
int len, pos[MAXA], lp[MAXN], rp[MAXN];
int cnt[MAXA], sum[MAXA][2];
int nowl, nowr;
inline void build(int N)
{
nowl = 1; nowr = 0;
len = max(1, (int)sqrt(N));
for(int i=0;i<=N;i++)
pos[i] = i/len+1;
for(int i=1;i<=pos[N];i++)
{
lp[i] = (i-1)*len;
rp[i] = min(N, i*len-1);
}
}
inline void add(int x)
{
if(x == -1) return;
if(cnt[x]) --sum[pos[x]][cnt[x]&1];
++cnt[x];
++sum[pos[x]][cnt[x]&1];
}
inline void del(int x)
{
if(x == -1) return ;
--sum[pos[x]][cnt[x]&1];
--cnt[x];
if(cnt[x]) ++sum[pos[x]][cnt[x]&1];
}
inline int query(int x, int tp)
{
int res = 0;
for(int i=1;i<pos[x];i++)
res += sum[i][tp];
for(int i=lp[pos[x]];i<=x;i++)
if(cnt[i] && (cnt[i]&1) == tp) ++res;
return res;
}
}B;
int pos[MAXN];
struct ques{
int l, r, ind, x, tp;
bool operator<(const ques&o)const{return pos[l]^pos[o.l]?pos[l]<pos[o.l]:pos[l]&1?r<o.r:r>o.r;}
}b[MAXN];
int ans[MAXN];
int a[MAXN];
int main()
{
// freopen("map12.in","r",stdin);
// freopen("mine.out","w",stdout);
n = read(); m = read();
int maxa = 0;
for(int i=1;i<=n;i++)
a[i] = read(), maxa = max(maxa, a[i]);
for(int i=1;i<=m;i++)
{
int u, v;
u = read(); v = read();
G.join(u, v);
G.join(v, u);
}
totn = n;
G.tarjan(1);
for(int i=n+1;i<=totn;i++)
a[i] = -1;
T.dfs(1);
q = read();
for(int i=1;i<=q;i++)
{
int u;
b[i].tp = read(); u = read(); b[i].x = read();
b[i].l = dfn[u];
b[i].r = dfn[u] + siz[u] - 1;
b[i].ind = i;
}
int len = sqrt(totn);
for(int i=1;i<=totn;i++)
pos[i] = (i-1)/len+1;
sort(b+1, b+q+1);
B.build(maxa);
for(int i=1;i<=q;i++)
{
while(B.nowl > b[i].l) B.add(a[rev[--B.nowl]]);
while(B.nowr < b[i].r) B.add(a[rev[++B.nowr]]);
while(B.nowl < b[i].l) B.del(a[rev[B.nowl++]]);
while(B.nowr > b[i].r) B.del(a[rev[B.nowr--]]);
ans[b[i].ind] = B.query(b[i].x, b[i].tp);
}
for(int i=1;i<=q;i++)
printf("%d\n",ans[i]);
return 0;
}