牛客网暑期ACM多校第三场G - 数论

题目链接:点击这里

 

解题思路:

处理这个问题之前我们先来考虑更简单的问题:

在长度为n的连续块上有m种染色颜料,而且距离小于等于k的块颜色不能相同的染色数是多少?

首先我们知道如果m

那么染色方案数为:m*(m-1)*(m-2)*(m-3)*...*(m-k+1)*(m-k+1)*(m-k+1)....

到第k块时它就会受到前面k-1块的限制,必须两两不同,所以他的可选择方案数就是(m-k+1)

那么回到现在的问题其实就是在树上解决这个问题,最后的答案就是距离大于等于d的方案数-距离大于等于d+1的方案数就是等于d的方案数了。

解决的关键就在于怎么找到两两受限的地方,那么我们通过广度搜索序(bfs)搜索就可以得到两两受限的数量,然后就可以得到该节点的可选方案数。

#include
using namespace std;
const int mx = 5e3 + 10;
const int mod = 1e9 + 7;
typedef long long ll;
int n,K,D,cnt[mx],top;
vector  vec[mx];
bool vis[mx];
void Order(int x,int d)
{
	queue  que;
	que.push(1);
	vis[1] = 1;
	while(!que.empty()){
		int no = que.front();
		que.pop();
		cnt[top++] = no;
		for(int v : vec[no]){
			if(vis[v]) continue;
			vis[v] = 1;
			que.push(v);
		}
	}
}
int dfs(int x,int fa,int d)
{
	if(d==D||!vis[x]) return 0;
	int ret = 1;
	for(int v : vec[x]){
		if(v==fa) continue;
		ret += dfs(v,x,d+1);
	}
	return ret;
}
ll solve()
{
	memset(vis,0,sizeof(vis));
	ll ans = 1;
	for(int i=0;i

 

你可能感兴趣的:(数论,dfs&bfs)