没用 dfs,但 4000ms,比别人慢几倍?
#include <bits/stdc++.h>
const int mod = 998244353, g = 3, gi = 332748118;
struct Fenwick{
int C[100005];
inline int lowbit(int x){
return x & -x;
}
inline int ask(int x);
inline void update(int x, int y);
};
inline int mul(int x, int y){
return (int)(1ll * x * y % (1ll * mod));
}
inline int add(int x, int y){
return x + y >= mod ? x + y - mod : x + y;
}
inline int minus(int x, int y){
return x < y ? x - y + mod : x - y;
}
inline int Qpow(int x, int y){
int r = 1;
while(y){
if(y & 1) r = mul(r, x);
x = mul(x, x);
y >>= 1;
}
return r;
}
void ntt(int *A, int limit, int on){
int rev[limit];
memset(rev, 0, sizeof(int) * limit);
for(int i = 1; i < limit; ++i)
rev[i] = (rev[i >> 1] >> 1) + (i & 1) * (limit >> 1);
for(int i = 0; i < limit; ++i)
if(i < rev[i]) std::swap(A[i], A[rev[i]]);
for(int i = 2; i <= limit; i <<= 1){
int t;
if(on == 1) t = Qpow(g, (mod - 1) / i);
else t = Qpow(gi, (mod - 1) / i);
for(int j = 0; j < limit; j += i){
int r = 1;
for(int k = j; k < j + i / 2; ++k, r = mul(r, t)){
int u = A[k], v = mul(A[k + i / 2], r);
A[k] = add(u, v);
A[k + i / 2] = minus(u, v);
}
}
}
if(on == -1){
int uu = Qpow(limit, mod - 2);
for(int i = 0; i < limit; ++i) A[i] = mul(A[i], uu);
}
return ;
}
inline int read(){
char c = getchar();
int x = 0;
while(c < '0' || c > '9') c = getchar();
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x;
}
int n, m, a[100005], d[100005];
std::vector <int> ver[100005], rev[100005];
int vis[100005], cnt, topo[100005];
long long ans;
std::bitset <405> t[100005];
void solve(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i) a[i] = read();
for(int i = 1; i <= n; ++i) d[i] = vis[i] = 0;
for(int i = 1; i <= n; ++i) ver[i].clear();
for(int i = 1; i <= n; ++i) rev[i].clear();
for(int i = 1; i <= m; ++i){
int x = read(), y = read();
ver[x].push_back(y);
ver[y].push_back(x);
++d[x], ++d[y];
}
std::queue <int> Q;
for(int i = 1; i <= n; ++i){
d[i] -= a[i];
if(d[i] == 0) Q.push(i), vis[i] = 1;
}
while(Q.size()){
int u = Q.front(); Q.pop();
for(auto v : ver[u])
if(!vis[v]){
rev[u].push_back(v);
--d[v];
if(d[v] == 0) Q.push(v), vis[v] = 1;
}
}
for(int i = 1; i <= n; ++i) d[i] = 0;
for(int i = 1; i <= n; ++i) for(auto v : rev[i]) ++d[v];
cnt = 0;
for(int i = 1; i <= n; ++i) if(!d[i]) Q.push(i), topo[++cnt] = i;
while(Q.size()){
int u = Q.front(); Q.pop();
for(auto v : rev[u]){
--d[v];
if(d[v] == 0) Q.push(v), topo[++cnt] = v;
}
}
ans = 0ll;
for(int i = 1; i <= n; i += 400){
for(int j = 1; j <= n; ++j) t[j].reset();
for(int j = n; j >= 1; --j){
int u = topo[j];
for(auto v : rev[u]) t[u] |= t[v];
ans += 1ll * t[u].count();
if(u >= i && u < i + 400) t[u][u - i] = 1;
}
}
printf("%lld\n", 1ll * n * (n - 1) / 2ll - ans);
return ;
}
int main(){
int T = 1;
scanf("%d", &T);
while(T--) solve();
return 0;
}