• 【BZOJ4872】分手是祝愿(期望DP)


    题意:

    B 君在玩一个游戏,这个游戏由 n 个灯和 n 个开关组成,给定这 n 个灯的初始状态,下标为
    从 1 到 n 的正整数。每个灯有两个状态亮和灭,我们用 1 来表示这个灯是亮的,用 0 表示这个灯是灭的,游戏
    的目标是使所有灯都灭掉。但是当操作第 i 个开关时,所有编号为 i 的约数(包括 1 和 i)的灯的状态都会被
    改变,即从亮变成灭,或者是从灭变成亮。B 君发现这个游戏很难,于是想到了这样的一个策略,每次等概率随机
    操作一个开关,直到所有灯都灭掉。这个策略需要的操作次数很多, B 君想到这样的一个优化。如果当前局面,
    可以通过操作小于等于 k 个开关使所有灯都灭掉,那么他将不再随机,直接选择操作次数最小的操作方法(这个
    策略显然小于等于 k 步)操作这些开关。B 君想知道按照这个策略(也就是先随机操作,最后小于等于 k 步,使
    用操作次数最小的操作方法)的操作次数的期望。这个期望可能很大,但是 B 君发现这个期望乘以 n 的阶乘一定
    是整数,所以他只需要知道这个整数对 100003 取模之后的结果。
    1 ≤ n ≤ 100000, 0 ≤ k ≤ n;
     
    思路:更正:下图中g[i]=((n-i)*g[i+1]+n)/i,官方题解谋财害命

    我不是很了解最后一张图在说什么

     1 const mo=100003;
     2 var head,a:array[1..200000]of longint;
     3     vet,next:array[1..5000000]of longint;
     4     exf,f,g:array[0..200000]of int64;
     5     n,k1,i,j,t,e,v,tot:longint;
     6     s,ans:int64;
     7 
     8 procedure add(a,b:longint);
     9 begin
    10  inc(tot);
    11  next[tot]:=head[a];
    12  vet[tot]:=b;
    13  head[a]:=tot;
    14 end;
    15 
    16 function mult(x,y:int64):int64;
    17 begin
    18  mult:=1;
    19  while y>0 do
    20  begin
    21   if y and 1=1 then mult:=mult*x mod mo;
    22   x:=x*x mod mo;
    23   y:=y>>1;
    24  end;
    25 end;
    26 
    27 begin
    28  assign(input,'bzoj4872.in'); reset(input);
    29  assign(output,'bzoj4872.out'); rewrite(output);
    30  readln(n,k1);
    31  exf[0]:=1; exf[1]:=1;
    32  for i:=2 to 100003 do exf[i]:=exf[mo mod i]*(mo-mo div i) mod mo;
    33  for i:=1 to n do read(a[i]);
    34  for i:=1 to n do
    35   for j:=1 to n div i do
    36   begin
    37    t:=j*i;
    38    add(t,i);
    39   end;
    40  for i:=n downto 1 do
    41   if a[i]=1 then
    42   begin
    43    inc(s);
    44    e:=head[i];
    45    while e<>0 do
    46    begin
    47     v:=vet[e];
    48     a[v]:=a[v] xor 1;
    49     e:=next[e];
    50    end;
    51   end;
    52  if s<=k1 then
    53  begin
    54   for i:=1 to n do s:=s*i mod mo;
    55   writeln(s);
    56   close(input);
    57   close(output);
    58   exit;
    59  end;
    60  g[n]:=1;
    61  for i:=n-1 downto k1+1 do
    62   g[i]:=(g[i+1]*(n-i) mod mo+n) mod mo*exf[i] mod mo;
    63  for i:=1 to k1 do g[i]:=1;
    64  for i:=0 to k1 do f[i]:=i;
    65  for i:=k1+1 to n do f[i]:=(f[i-1]+g[i]) mod mo;
    66  ans:=f[s];
    67  for i:=1 to n do ans:=ans*i mod mo;
    68  writeln(ans);
    69  close(input);
    70  close(output);
    71 end.
  • 相关阅读:
    python scapy的用法之ARP主机扫描和ARP欺骗
    Python字典取键、值对
    python字典添加元素和删除元素
    Python删除列表元素
    获取本机的IP地址和mac地址
    Python查找电话号码归属地、邮编、运营商信息等
    Python的字符串格式化,%与format
    Python基础笔记一之字符转化、复数、位运算、除法运算、floor和ceil取整,round函数四舍五入
    FAILED: SemanticException Unable to determine if hdfs://tmaster:8020/user/root/words.db/test_t2 is encrypted
    Pyspark读取csv文件
  • 原文地址:https://www.cnblogs.com/myx12345/p/6769466.html
Copyright © 2020-2023  润新知