[洛谷P3937]Changing

题目大意:有 $n$ 盏灯环形排列,顺时针依次标号为 $1cdots n$。初始时刻为 $0$ ,初始时刻第 $i$ 盏灯的亮灭 $a_i$, $0$ 表示灭, $1$ 表示亮。下一时刻每盏灯的亮灭取决于当前时刻这盏灯与顺时针方向下一盏灯的亮灭。若两盏灯状态相同,则下一时刻该灯灭,否则该灯亮。试求时刻 $t$ 第 $k$ 盏灯的状态。

题解:时刻 $t$ 第 $k$ 盏灯的状态为

$$f_{t,k}=left( sumlimits_{i=0}^t C_t^i a_{(k+i-1) mod{(n+1)}} ight) mod{2}$$

$$egin{align*}
ecause f_{t,k}&=f_{t-1,k}oplus f_{t-1,k+1}\
&=(f_{t-1,k}+f_{t-1,k+1})mod{2}\
&=(f_{t-2,k}+2cdot f_{t-2,k+1}+f_{t-2,k+2})mod{2}\
&=(f_{t-3,k}+3cdot f_{t-3,k+1}+3cdot f_{t-3,k+2}+f_{t-3,k+2})mod{2}\
&dots
end{align*}$$

卡点:算一个数含有几个因数$2$时算错

C++ Code:

#include <cstdio>
#define maxn 3000010
using namespace std;
int count(int i) {
	int ans = 0, tmp = i & -i;
	while (tmp >>= 1) ans++;
	return ans;
}
int n, t, k, ans;
int a[maxn], fac[maxn];
int C(int a, int b) {return fac[a] - fac[b] - fac[a - b] == 0;}
int main() {
	scanf("%d%d%d", &n, &t, &k);
	for (int i = 0; i < n; i++) scanf("%d", &a[i]);
	k--;
	for (int i = 1; i <= t; i++) fac[i] = fac[i - 1] + count(i);
	for (int i = 0; i <= t; i++) {
		ans ^= C(t, i) & a[(k + i) % n];
	}
	printf("%d
", ans);
	return 0;
}

  

原文地址:https://www.cnblogs.com/Memory-of-winter/p/9487055.html