统计满足下列条件的集合对(A, B)的数量:
A,B都是{1, 2, …, N}的子集;
A,B没有公共的元素;
f(A)<= f(B)。f(S)定义为S中所有元素的按位异或和。例如, f({}) = 0, f({1, 3}) = 2。
因为答案可能很大,你只需要求出它除以M的余数。
第一行一个整数T (1 ≤ T ≤ 10),表示数据组数。
接下来是T组输入数据,测试数据之间没有空行。
每组数据格式如下:
仅一行,2个整数N和M (1 ≤ M ≤ 108)。
对每组数据,先输出“Case x: ”,然后接一个整数,表示所求的结果。
小数据:1 ≤ N ≤ 20
大数据:1 ≤ N < 212
1 3 100000000
Case 1: 18
const int MAXN = 1100; const double PI = acos(-1.0); int dp[MAXN]; int main() { // freopen("in.txt", "r", stdin); int n; while (cin >> n) { CLR(dp, 0); int all = (1 << n) - 1; for (int i = 1, cnt = 1; cnt <= n; cnt++, i <<= 1) { FED(j, all, 0) { if (j & i) { dp[j] = dp[i ^ j] ^ cnt; } } } int ans = 0; FE(i, 0, all) FE(j, 0, all) { if (!(i & j) && dp[i] >= dp[j]) ans++; } WI(ans); } return 0; }
const int MAXN = 1100; const double PI = acos(-1.0); LL dp[2][MAXN]; LL my(int n) { LL ret = 1; for (int i = 0; i < n; i++) ret *= 3; return ret; } int main() { // freopen("in.txt", "r", stdin); int n; while (cin >> n) { int cur = 0, all; CLR(dp, 0); dp[cur][0] = 1; for (all = 1; all <= n; all <<= 1); all -= 1; for (int cnt = 1; cnt <= n; cnt++) { cur ^= 1; CLR(dp[cur], 0); FE(j, 0, all) { dp[cur][j] += dp[cur ^ 1][j]; dp[cur][j ^ cnt] += dp[cur ^ 1][j] * 2; } } cout << (my(n) + dp[cur][0]) / 2 << endl; } return 0; }
原文:http://blog.csdn.net/wty__/article/details/24190839