Description:
学生都很喜欢灌水,第一天只有Alice给她的每个朋友灌了一次水,从第二天开始,所有学生(包括Alice)将会有规律地去灌水:
•如果前一天被灌了奇数次的水,他们将会给每个朋友灌一次水;
•如果前一天被灌了偶数次的水,他们将会给每个朋友灌两次水。
学生编号为1到N,Alice为1号,学生之间的朋友关系会给出。
计算H天后一共灌了几次水。
Input
输入1:
4 1
0110
1001
1001
0110
输入2:
4 2
0110
1001
1001
0110
输入3:
5 3
01000
10110
01000
01001
00010
Output
输出1:
2
输出2:
14
输出3:
26
Solution
更新状压状态T直至出现循环。
至于为什么。。。“自行脑补”——AK晗。
Program
var
c:char;
y,e,ans:int64;
i,j,k,n,h,t:longint;
f,w:array [0..1050000] of longint;
d:array [1..20,0..20] of longint;
m:array [1..20] of longint;
begin
readln(n,h);
for i:=1 to n do
begin
for j:=1 to n do
begin
read(c);
if c='1' then
begin
inc(d[i][0]);
d[i][d[i][0]]:=j;
end;
end;
readln;
end;
m[1]:=1;
for i:=2 to n do
m[i]:=m[i-1]*2;
for i:=1 to d[1][0] do
t:=t+m[d[1][i]];
e:=d[1][0];
f[t]:=1;
w[t]:=e;
for k:=2 to h do
begin
y:=t;
t:=0;
for i:=1 to n do
if y and m[i]<>0 then
begin
for j:=1 to d[i][0] do
if t and m[d[i][j]]<>0 then
t:=t-m[d[i][j]]
else
t:=t+m[d[i][j]];
e:=e+d[i][0];
end else
begin
e:=e+d[i][0]*2;
end;
if f[t]=0 then
begin
f[t]:=k;
w[t]:=e;
end else
begin
ans:=w[t]+(h-f[t]) div (k-f[t])*(e-w[t]);
h:=h-f[t];
h:=h mod (k-f[t]);
break;
end;
end;
if ans<>0 then
begin
e:=0;
for k:=1 to h do
begin
y:=t;
t:=0;
for i:=1 to n do
if y and m[i]<>0 then
begin
for j:=1 to d[i][0] do
if t and m[d[i][j]]<>0 then
t:=t-m[d[i][j]]
else
t:=t+m[d[i][j]];
e:=e+d[i][0];
end else
begin
e:=e+d[i][0]*2;
end;
end;
end;
writeln(ans+e);
end.