1 条题解
-
0
// poj3875 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #define LL long long #define inf 2147483640 #define MOD 10567201 #define Pi acos(-1,0) #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); using namespace std; const int maxn=2000; LL f[maxn],fac[maxn],C[maxn]; int n,m,v; LL power(LL a,LL b) { LL res=1; while (b) { if (b&1) res=res*a%MOD; b>>=1;a=a*a%MOD; } return res; } int main() { fac[0]=1;for (int i=1;i<=1000;i++) fac[i]=fac[i-1]*i%MOD; while (scanf("%d%d%d",&n,&m,&v)!=EOF) { if (!n && !m && !v) break; LL tmp=power(2,n); C[0]=1; for (int i=1;i<=m;i++) { int inv=power(i,MOD-2); C[i]=C[i-1]*(tmp-i+1)%MOD*inv%MOD; } f[1]=1;f[0]=0;if (v==0) f[2]=0;else f[2]=tmp; for (int i=3;i<=m;i++) { f[i]=(fac[i-1]*C[i-1]%MOD-(i-1)*(tmp-(i-2))%MOD*f[i-2]%MOD+MOD)%MOD; } LL inv=power(fac[m],MOD-2); printf("%lld\n",inv*f[m]%MOD); } return 0; }
问题分析 状态表示:每个灯泡状态可视为 n 位二进制数,前 v 位为 1、后 n-v 位为 0 是目标状态,记为 T。 操作本质:每次操作选择一个开关集合 S,相当于对当前状态异或一个二进制数 s(S 中开关对应位为 1,其余为 0)。 关键观察:m 次操作的开关集合 s₁, s₂, ..., sₘ 需满足 s₁ ^ s₂ ^ ... ^ sₘ = T(异或和为目标状态),且所有 sᵢ 互不相同。
- 1
信息
- ID
- 2869
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者