高中Oj1434. 灌水

来源:互联网 发布:tina仿真软件下载 编辑:程序博客网 时间:2024/04/29 12:38

https://jzoj.net/senior/#main/show/1434


这道题的暴力是显然的,我们只需对上一次灌水做一个标记,判断是被灌了奇数次还是偶数次,奇数次的再去改变其他人的状态即可。

注意,这里n<=20,那么对于每一个人的标记总数只有2^20种,而h却为10^9,很明显我们可以采取周期策略。

如下图:



代码:

var        date,value:Array[0..1500000] of int64;        x:array[1..20] of longint;        bz:array[1..20] of boolean;        ch:array[1..20,1..20] of char;        n,h,i,j,k,ans,sum,w,xmod,xdiv:Longint;begin        readln(n,h);        for i:=1 to n do        begin                for j:=1 to n do                        read(ch[i,j]);                readln;        end;        for i:=1 to n do                if ch[1,i]='1' then                begin                        bz[i]:=true;                        inc(ans);                end;        for k:=1 to h-1 do        begin                w:=0;                for i:=1 to n do                        if bz[i] then inc(w,1 shl (i-1));                if date[w]=0 then                begin                        date[w]:=k;                        value[k]:=ans;                end                else                begin                        value[k]:=ans;                        xmod:=(h-k) mod (k-date[w]);                        xdiv:=(h-k) div (k-date[w]);                        writeln(xdiv*(value[k]-value[date[w]])+value[date[w]+xmod]-value[date[w]]+value[k]);                        halt;                end;                fillchar(x,sizeof(x),0);                sum:=0;                for i:=1 to n do                        if bz[i] then                        begin                                for j:=1 to n do                                        if ch[i,j]='1' then                                        begin                                                inc(x[j]);                                                inc(sum);                                        end;                        end                        else                        begin                                for j:=1 to n do                                        if ch[i,j]='1' then inc(sum,2);                        end;                inc(ans,sum);                fillchar(bz,sizeof(bz),0);                for i:=1 to n do                        if x[i] mod 2=1 then bz[i]:=true;        end;        writeln(ans);end.


0 0