bzoj-2126: 排斥反应

96 篇文章 0 订阅
11 篇文章 0 订阅

2126: 排斥反应

Time Limit: 40 Sec   Memory Limit: 259 MB
Submit: 190   Solved: 90
[ Submit][ Status]

Description

在一个圆上均匀分布p*q个点{A1,A2,A3…Ap*q},Ai与Aj的距离为min{abs(i-j),p*q-abs(i-j)},在上面选任意个点(可以选0个),如果选择的点中存在两个点距离为p或q,就会发生排斥反应,求不发生排斥反应的方案总数。

Input

输入的第一行包含两个整数,分别表示p和q

Output

输出一个整数,表示方案总数,由于这个题答案可能很大,只要输出答案mod 19921107

Sample Input

1 6

Sample Output

18
【数据说明】
对于100%的数据,p<=10,q<=10^9,p和q互质

HINT
  
  这真是道神题,看范围像是状压DP,但完全不会,去看题解,真是太神了,把所有点之间的关系用一个P*Q的矩阵表示,则相邻的两

个点之间会发生排斥,所以问题转化为求从P*Q矩阵中选任意多个点两两不相邻的方案数为多少,预处理出状态间的转移系数,最后再

用矩阵快速幂
加速就行了,注意矩阵的左右上下边界都是联通的。

/**************************************************************
    Problem: 2126
    User: WZJRJ28
    Language: Pascal
    Result: Accepted
    Time:29672 ms
    Memory:1164 kb
****************************************************************/
  
var
 i,j,k,tot,ans:longint;
 p,q,y:int64;
 jud:boolean;
 f:array [1..200] of int64;
 a,t,tt:array [1..200,1..200] of int64;
procedure dfs(k,z:int64);
begin
 if k>p then
  begin
   inc(TOT);
   f[tot]:=z;
   exit;
  end;
 dfs(k+1,z);
 if (z and 1<>1)or(k<>p) then dfs(k+2,z+(1 shl (k-1)));
end;
begin
 read (p,q);
 dfs(1,0);
 for i:=1 to tot do
  for j:=1 to tot do
   if f[i] and f[j]=0 then a[i,j]:=1;
 y:=q-1;
 if y=0 then
  begin
   writeln(tot);
   exit;
  end;
 jud:=true;
 while y<>0 do
  begin
   if y and 1=1 then
    if jud then
     begin
      jud:=false;
      t:=a;
     end
           else
     begin
      fillchar (tt,sizeof(tt),0);
      for i:=1 to tot do
       for j:=1 to tot do
        for k:=1 to tot do
         tt[i,j]:=(tt[i,j]+t[i,k]*a[k,j])mod 19921107;
      t:=tt;
     end;
    fillchar (tt,sizeof(tt),0);
    for i:=1 to tot do
     for j:=1 to tot do
      for k:=1 to tot do
       tt[i,j]:=(tt[i,j]+a[i,k]*a[k,j])mod 19921107;
    a:=tt;
    y:=y shr 1;
  end;
 for i:=1 to tot do
  for j:=1 to tot do
   if f[i] and f[j]=0 then
    ans:=(ans+t[i,j]) mod 19921107;
 writeln(ans);
end.


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值