为什么跑的这么慢呢
查看原帖
为什么跑的这么慢呢
131591
蒟蒻君HJT泽渡透香楼主2023/2/19 18:02

没用 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;
}



2023/2/19 18:02
加载中...