萌新求助 DFS
查看原帖
萌新求助 DFS
119491
5ab_juruo楼主2021/10/4 22:55

rt,下面是我的代码:

#include <iostream>
#include <cstring>
using namespace std;

typedef long long ll;
const int max_n = 1000, mod = int(1e9) + 7;

int a[max_n], hd[max_n], des[max_n<<1], nxt[max_n<<1], e_cnt, vis[max_n];
ll f[max_n+1];

void add(int s, int t)
{
	des[e_cnt] = t;
	nxt[e_cnt] = hd[s];
	hd[s] = e_cnt++;
}

ll qpow(ll bs, ll ix)
{
	ll cur = 1, mul = bs, ret = 1;
	while (cur <= ix)
	{
		if (cur & ix)
			ret = (ret * mul) % mod;
		mul = (mul * mul) % mod;
		cur <<= 1;
	}
	
	return ret;
}

void dfs(int id)
{
	for (int p = hd[id]; p != -1; p = nxt[p])
		if (!vis[des[p]])
		{
			vis[des[p]] = 114514191;
			dfs(des[p]);
		}
}

signed main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	
	int n, k, cas, cnt, ind, sti;
	ll ans;
	
	cin >> cas;
	while (cas--)
	{
		memset(hd, -1, sizeof hd);
		memset(vis, 0, sizeof vis);
		
		cin >> n >> k, e_cnt = 0, cnt = 0;
		for (int i = 0; i < n; i++)	
		{
			cin >> a[i];
			add(i, a[i]), add(a[i], i);
		}
		
		f[1] = k, f[2] = k * (k - 1), f[3] = f[2] * (k - 2) % mod;
		for (int i = 4; i <= n; i++)
			f[i] = (f[i-1] * (k - 2) + f[i-2] * (k - 1)) % mod;
		
		ind = 1, ans = 1;
		for (int i = 0, ptr; i < n; i++)
			if (!vis[i])
			{
				ptr = i, sti = ind;
				while (!vis[ptr])
				{
					vis[ptr] = ind++;
					ptr = a[ptr];
				}
				
				if (sti <= vis[ptr])
				{
					ans = ans * f[ind-vis[ptr]] % mod;
					cnt += ind - vis[ptr];
				}
				
				// do {
				// 	dfs(ptr);
				// 	ptr = a[ptr];
				// } while (vis[ptr] < ind - 1);
			}
		
		cout << ans * qpow(k - 1, n - cnt) % mod << endl;
	}
	
	return 0;
}

注释部分是给基环树剩余部分打标记避免再次计算的,但加上这部分导致了 TLE。而删去后改用检查时间戳就过了。

题解好像都是这么写的,好像也不是性能问题,所以这是为什么呢?求助。

2021/10/4 22:55
加载中...