Description

在一个圆上均匀分布pq个点{A1,A2,A3…Apq},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

Data Constraint

对于5%的数据,p=1,q<=10^6
  对于15%的数据,p=1,q<=10^9
  对于100%的数据,p<=10,q<=10^9,p和q互质

题解

这题好秒啊♂。
虽说连15分都八会,而且一点也不吸引人。

首先对于p=1的情况(%15)
那么我们可以考虑设一个dp方程:
f[i][0..1]f_{[i][0..1]}f[i][0..1]​表示当前第i个格子填0/1的答案。
这个其实很好转移,但是这样只能拿5分的好成绩。
但是,我们观察柿子,可以发现答案其实就是斐波那契数列的第q项加上第q-2项。
矩阵优化即可得到15分。

那么当p>1时呢?
由于同时保证p和q有点烦,直接维护显然不太现实。
得要换个思路来做。

这里有个神奇的方法:
假设现在询问p=5,q=6
那么我们考虑列出一个方格表:
(1,1)这个位置是1,其余都是0。现在从(1,1)出发,每次往右走一格就是+q,往下走一格就是+p。当然,如果超过了是modp∗qmod\ p*qmod p∗q
得到:

然后我们惊奇地发现,其中所有格子都出现了不重复的数,范围是1−p∗q1-p*q1−p∗q
为什么呢?

证明:
可以一列一列来看。
那么我们发现,对于第一列都是模q=1的,对于第二列都是模q=0的,对于第三列都是模q=5的……依次类推。
所以我们只需要证明一个东西:当x取0到q-1时满足x∗p(modq)x*p(mod\ q)x∗p(mod q)是互不相同的。
那么假设x1∗p(modq)x1*p(mod\ q)x1∗p(mod q)和x2∗p(modq)x2*p(mod\ q)x2∗p(mod q)相等
可列得:x1∗p−x2∗p=y∗qx1*p-x2*p=y*qx1∗p−x2∗p=y∗q
然后解一解可以发现,x1−x2=z∗q(z∈Z)x1-x2=z*q(z\in Z)x1−x2=z∗q(z∈Z)
那么就证明了在p*q以内是不会发生重复的。

那么再反过来看这道题,我们发现,问题就变成了:
在p*q的格子中放入若干个棋子,棋子之间不能相连(首尾上下相接也算不合法)
p那么小,状压。状压状态又有很多没有用的状态就优化掉,最多只有123种。
那么愉快矩乘优化即可。

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const int mo=19921107;struct node
{long long a[3][3];
};
struct node1
{long long a[124][124];
};int p,q,gs,op[1024],mi[12];
node f;
node1 zy;node1 chengg(node1 x,node1 y,int p)
{node1 c;memset(c.a,0,sizeof(c.a));for (int i=1;i<=p;i++){for (int j=1;j<=p;j++){for (int k=1;k<=p;k++){c.a[i][j]=(c.a[i][j]+x.a[i][k]*y.a[k][j])%mo;}}}return c;
}node1 qsm1(node1 a,long long b)
{node1 t;memcpy(t.a,a.a,sizeof(t.a));node1 y;memcpy(y.a,a.a,sizeof(y.a));while (b>0){if ((b&1)==1) t=chengg(t,y,gs);y=chengg(y,y,gs);b/=2;} return t;
}node cheng(node x,node y)
{node c;memset(c.a,0,sizeof(c.a));for (int i=1;i<=2;i++){for (int j=1;j<=2;j++){for (int k=1;k<=2;k++){c.a[i][j]=(c.a[i][j]+x.a[i][k]*y.a[k][j])%mo;}}}return c;
}node qsm(node a,long long b)
{node t;t.a[1][1]=0;t.a[1][2]=1;t.a[2][1]=1;t.a[2][2]=1;node y;memcpy(y.a,a.a,sizeof(y.a));while (b>0){if ((b&1)==1) t=cheng(t,y);y=cheng(y,y);b/=2;} return t;
}long long get(int x)
{node t;t.a[1][1]=0;t.a[1][2]=1;t.a[2][1]=1;t.a[2][2]=1;node y=qsm(t,x-2);memset(t.a,0,sizeof(t.a));t.a[1][2]=1;y=cheng(y,t);return y.a[2][2];
}int main()
{freopen("data.in","r",stdin);mi[0]=1;for (int i=1;i<=10;i++){mi[i]=mi[i-1]*2;}scanf("%d%d",&p,&q);if (p==1){long long a=get(q);long long b=get(q+2);printf("%lld\n",(a+b)%mo);return 0;}for (int i=0;i<=mi[p]-1;i++){if (i==128){int j=0;}bool pd=true;for (int j=2;j<=p;j++){if ((mi[j-1]&i)!=0 && (mi[j-2]&i)!=0){pd=false;break;}}if ((mi[0]&i)!=0 && (mi[p-1]&i)!=0){pd=false;}if (pd==true){gs++;op[gs]=i;} }if (q==1){printf("%d\n",gs);return 0;}for (int i=1;i<=gs;i++){for (int j=1;j<=gs;j++){if ((op[i]&op[j])==0){zy.a[i][j]=1;}}}zy=qsm1(zy,q-2);long long ans=0;for (int i=1;i<=gs;i++){for (int j=1;j<=gs;j++){if ((op[i]&op[j])==0){ans=(ans+zy.a[i][j])%mo;}}}printf("%lld\n",ans);
}

jzoj1915. 【2011集训队出题】排斥反应相关推荐

  1. 【2011集训队出题】跳跳棋

    [2011集训队出题]跳跳棋 Time Limits: 1000 ms Memory Limits: 128000 KB Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点 ...

  2. JZOJ 1980. 【2011集训队出题】Construct

    Description 随着改革开放的深入推进-- 小T家要拆迁了-- 当对未来生活充满美好憧憬的小T看到拆迁协议书的时候,小T从一位大好的社会主义青年变成了绝望的钉子户. 由于小T的家位于市中心,拆 ...

  3. bzoj2144 [2011集训队出题] 跳跳棋 倍增 lca

    Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把 ...

  4. 【2011集训队出题】拆迁队

    Description: lanxisi带领着他的拆迁队来整治一个街道.这个街道由N个旧房子组成,从左到右编号为1..N.每个旧房子i有一个正整数的美观度Ai. lanxisi希望整个街道从左到右美观 ...

  5. [JZOJ1901] 【2010集训队出题】光棱坦克

    题目 题目大意 给你个平面上的一堆点,问序列pi{p_i}pi​的个数. 满足ypi−1>ypiy_{p_{i-1}}>y_{p_i}ypi−1​​>ypi​​并且xpix_{p_i ...

  6. 【2019暑假集训】08.07比赛总结

    省选组真的比A组简单...远古时期的集训队出题难度都不大 比赛思路 传送门 T1( 拯救Protoss的故乡):树形DP???暴力操作显然不可行.模型很像网络流,有的边费用为0,有的边费用为1,所以直 ...

  7. happiness[国家集训队2011(吴确)]

    [试题来源] 2011中国国家集训队命题答辩 [问题描述] 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科 ...

  8. 国家集训队2011 happiness

    [试题来源] 2011中国国家集训队命题答辩 [问题描述] 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科 ...

  9. [国家集训队2011]跳跳棋

    P1852 [国家集训队]跳跳棋https://www.luogu.org/problemnew/show/P1852 Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不 ...

  10. [国家集训队2011]稳定婚姻(无向图定向)

    题目描述 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有关. 25岁的姗姗和男友谈恋爱半年就结婚,结婚不到 ...

最新文章

  1. 【Python-ML】SKlearn库L1正则化特征选择
  2. 音视频编解码的国际标准
  3. 能让你纵享丝滑的SSR技术,转转这样实践
  4. php映射,PHP实现路由映射到指定控制器
  5. 怎么将tflite部署在安卓上_tensorflow从训练自定义CNN网络模型到Android端部署tflite...
  6. 安卓学习笔记05:Activity概述
  7. Linux在线升级ruby
  8. Google的特殊功能
  9. 智能优化算法:基于梯度的优化算法-附代码
  10. 庖丁解牛之spring源码系列二 spring bean生命周期介绍
  11. 身份证读取设备开发解决方案:3、单片机读取身份证信息的demo
  12. html5广告拦截器识别代码做提示(本站内容无法显示)
  13. 山水功放与音箱接线图_功放音响线接法图解
  14. paint.net ps证件照背景色
  15. 思考篇|姜子牙观影后感
  16. redis-发布与订阅
  17. winrar去掉烦人的广告 亲测有效
  18. SyncToy本地备份工具安装使用+taskschd.msc定时备份
  19. NXP Nfc模块Framework层移植遇到的坑【二】
  20. 天邑ty1208z海思3798刷版本_天邑TY1208Z海思3798芯片强刷安卓系统固件rom刷机包下载...

热门文章

  1. AIDE手机编程初级教程(零基础向)导航
  2. ILSpy c#反编译工具,附下载地址
  3. Logisim实现运动码表
  4. Java 加密、解密PDF文档
  5. DarkAngels勒索病毒分析
  6. SQL Server 的完整下载安装教程
  7. 养老院管理系统如何开发详解
  8. 学习笔记-Matlab算法篇-动态规划
  9. KaliLinux-masscan使用详解(全网最快的IP端口扫描神器)
  10. 冒泡排序C语言实现(源代码)