Codeforces 217D Bitonix' Patrol (dfs + bitset)

#include <bits/stdc++.h>
using namespace std;


#define N 122
#define mod 1000000007

bool vis[N];
int cnt[N], x[N];
int n, m, k;
bitset<N*2> s[8];
int ans;

int getAns(int d) {
	int ret = 1;
	for(int i = 1; i < d; ++i) {
		ret = 1LL * ret * cnt[x[i]] % mod;
	}
	return ret;
}

int v[N+N+N];

int g(int x) {
	if(x >= m) x -= m;
	return x;
}

int dfs(int d, int last) {
	int ret = getAns(d);
	if(d <= 6) {
		for(int i = last + 1; i <= m / 2; ++i) {
			if(!cnt[i]) continue;
			if(s[d-1][i] || s[d-1][m-i]) continue;
			x[d] = i;
			if(d <= 5) {
				s[d] = s[d-1];
				s[d] |= s[d-1] << i;
				s[d] |= s[d-1] >> i;
				s[d] |= s[d-1] >> (m - i);
				s[d] |= s[d-1] << (m - i);
			}
			ret += dfs(d + 1, i);
			if(ret >= mod) ret -= mod;
		}
	}
	return ret;
}






int main() {
	scanf("%d%d%d", &n, &m, &k);
	for(int i = 0; i < 3 * N; ++i) v[i] = i % m;
	for(int i = 1; i <= k; ++i) {
		int x;
		scanf("%d", &x);
		x %= m;
		x = min(x, m - x);
		vis[x] = 1;
		cnt[x]++;
	}
	s[0][0] = 1;
	ans = dfs(1, 0);
	printf("%d\n", ans);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值