$n \leq 500$,$2-n$这些数字,两个人挑,可以重复挑,问有几种方案中,一个人选的所有数字与另一个人选的所有数字都互质。

不像前两题那么抠脚。。

如果$n$比较小的话,可以把两个人选的数字对应的质因子状压一下,$f(i,j,k)$--前$i$个数,第一个人选状态$j$,第二个人选状态$k$,状态表示质因子。

质因子的根号相关性质:根号n之后的每个质因子最多只会在一个数里出现一次。也就是说,对根号n前面的质因子我们是可能一次选若干种的,但根号n后面的每个质因子每次只能选一种,所以可以单独枚举,再用根号n以前的状态表示。$g(i,j,k)$--前$i$个含质数$p$的数,只让第一个人选,第二个人保持状态$k$的方案数;$h(i,j,k)$--前$i$个含质数$p$的数,只让第二个人选,第一个人保持状态$j$的方案数。如此dp完,$ans(j,k)$表示最后的$f(i,j,k)$,那么$ans(j,k)=g(t,j,k)+h(t,j,k)-ans(j,k)$,其中$t$表示含质因数$p$的数的个数,因为两个人都不选的方案算了两次。

 //#include<iostream>
#include<cstring>
#include<cstdio>
//#include<math.h>
//#include<set>
//#include<queue>
//#include<bitset>
//#include<vector>
#include<algorithm>
#include<stdlib.h>
using namespace std; #define LL long long
int qread()
{
char c; int s=,f=; while ((c=getchar())<'' || c>'') (c=='-') && (f=-);
do s=s*+c-''; while ((c=getchar())>='' && c<=''); return s*f;
} //Pay attention to '-' , LL and double of qread!!!! int n,mod;
#define maxn 555
int f[][maxn][maxn],g[][maxn][maxn],h[][maxn][maxn],cur=; int prime[maxn],lp,xx[maxn],ss[maxn]; bool notprime[maxn];
void makeprime()
{
ss[]=; ss[]=; ss[]=; ss[]=;
ss[]=; ss[]=; ss[]=; ss[]=;
for (int i=;i<=n;i++)
{
if (!notprime[i]) {prime[++lp]=i; xx[i]=i;}
for (int j=,tmp;j<=lp && 1ll*i*prime[j]<=n;j++)
{
notprime[tmp=i*prime[j]]=;
xx[tmp]=prime[j];
if (!(i%prime[j])) break;
}
}
} int num[maxn],len; int S,P;
void mm(int x)
{
len=;
while (x>) {num[++len]=xx[x]; x/=xx[x];}
sort(num+,num++len); len=unique(num+,num++len)-num-;
S=; for (int i=;i<=len;i++) if (num[i]<=) S|=<<ss[num[i]];
if (num[len]>) P=num[len]; else P=;
} int list[maxn][maxn];
void play(int &x,int v) {x+=v; x-=x>=mod?mod:;}
int main()
{
n=qread(); mod=qread();
makeprime();
for (int i=;i<=n;i++) {mm(i); list[P][++list[P][]]=S;} int ts=<<; f[][][]=; cur=;
for (int i=;i<=list[][];i++)
{
int u=list[][i];
memset(f[cur^],,sizeof(f[cur^]));
for (int j=;j<ts;j++)
for (int k=;k<ts;k++) if (f[cur][j][k])
{
play(f[cur^][j][k],f[cur][j][k]);
int nj=j|u; if ((nj&k)==) play(f[cur^][nj][k],f[cur][j][k]);
int nk=k|u; if ((j&nk)==) play(f[cur^][j][nk],f[cur][j][k]);
}
cur^=;
} for (int j=;j<ts;j++)
for (int k=;k<ts;k++)
f[][j][k]=f[cur][j][k];
for (int i=;i<=n;i++) if (!notprime[i])
{
cur=;
for (int j=;j<ts;j++)
for (int k=;k<ts;k++)
g[][j][k]=f[][j][k],h[][j][k]=f[][j][k];
for (int t=;t<=list[i][];t++)
{
int u=list[i][t];
memset(g[cur^],,sizeof(g[cur^]));
memset(h[cur^],,sizeof(h[cur^]));
for (int j=;j<ts;j++)
for (int k=;k<ts;k++) if (g[cur][j][k])
{
play(g[cur^][j][k],g[cur][j][k]);
int nj=j|u; if ((nj&k)==) play(g[cur^][nj][k],g[cur][j][k]);
}
for (int j=;j<ts;j++)
for (int k=;k<ts;k++) if (h[cur][j][k])
{
play(h[cur^][j][k],h[cur][j][k]);
int nk=k|u; if ((j&nk)==) play(h[cur^][j][nk],h[cur][j][k]);
}
cur^=;
}
for (int j=;j<ts;j++)
for (int k=;k<ts;k++)
f[][j][k]=((g[cur][j][k]+h[cur][j][k]-f[][j][k])%mod+mod)%mod;
} int ans=;
for (int j=;j<ts;j++)
for (int k=;k<ts;k++)
play(ans,f[][j][k]);
printf("%d\n",ans);
return ;
}

LOJ#2131. 「NOI2015」寿司晚宴的更多相关文章

  1. 【LOJ】#2131. 「NOI2015」寿司晚宴

    题解 怎么NOI2015D1--全是一眼秒的sb题--然后我代码全都写跪一遍= = 要是NOI2015是IOI赛制我就可以AK啦(大雾) 代码能力直线下降,NOI2018滚粗预定了啊TAT 我是不是要 ...

  2. 「NOI2015」寿司晚宴 解题报告

    「NOI2015」寿司晚宴 这个题思路其实挺自然的,但是我太傻了...最开始想着钦定一些,结果发现假了.. 首先一个比较套路的事情是状压前8个质数,后面的只会在一个数出现一次的再想办法就好. 然后发现 ...

  3. loj#2129. 「NOI2015」程序自动分析

    题目链接 loj#2129. 「NOI2015」程序自动分析 题解 额... 考你会不会离散化优化常数 代码 #include<queue> #include<cstdio> ...

  4. *LOJ#2134. 「NOI2015」小园丁与老司机

    $n \leq 5e4$个平面上的点,从原点出发,能从当前点向左.右.上.左上或右上到达该方向最近的给定点.问三个问:一.最多经过多少点:二.前一问的方案:三.其所有方案种非左右走的边至少要开几辆挖掘 ...

  5. LOJ#2132. 「NOI2015」荷马史诗

    $n \leq 100000$个数字,放进$k$叉树里,一个点只能放一个数,使所有数字乘以各自深度这个值之和最小的同时,最大深度的数字最小. 哈夫曼.这是我刚学OI那段时间看到的,感觉就是个很无聊的贪 ...

  6. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

  7. Loj #3096. 「SNOI2019」数论

    Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...

  8. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

  9. Loj #3089. 「BJOI2019」奥术神杖

    Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...

随机推荐

  1. popen和pclose详解及实例

    popen函数是标准c提供的一个管道创建函数,其内部操作主 要是创建一个管道,调用fork创建子进程,关闭不需用的文件描述符,调用exec函数族执行popen的第一个参数.然后等到关闭. 也就是说我们 ...

  2. 为什么90%的IT人员都不适合做老大?

    什么是格局? 格局就是能够很好的平衡短期利益和长期利益. 过分注重短期利益的人必然会失去长期利益,到头来一定会很普通. 例如:跳槽不断,可能短期薪资会增长,但长期来看后劲可能会不足,未来发展空间会变窄 ...

  3. linux文件属性之时间戳及文件名属性知识

    7  8  9 三列是时间(默认是修改时间) modify 修改时间  -mtime  修改文件内容 change 改变时间 -ctime  文件属性改变 access 访问时间  -atime  访 ...

  4. java中的继承 (2013-10-11-163 写的日志迁移

    继承:为了解决代码重用 定义: 子类通过继承父类,可以调用父类中非私有的属性和方法,达到重用的目的,通过关键字extends实现:   ################以下为代码演示: class A ...

  5. 数据结构-单链表(Linked List)

    #include <stdio.h> #include <stdlib.h> #define LIST_INIT_SIZE 10 #define LISTINCREMENT 1 ...

  6. linux批量替换

    sed -i "s/李三/李四/g"  -r result/*       将result文件夹下的所有文件中的李三替换成李四 sed命令下批量替换文件内容  格式: sed -i ...

  7. Linux 用户行为日志记录

    工作中我们常常遇到,有的员工不安于被分配的权限,老是想sudo echo "ziji" /usr/bin/visudo NOPASSWD:ALL来进行提权,造成误删了数据库某条重要 ...

  8. 用私有构造器或者枚举类型强化Singleton属性

    1.Singleton指仅仅被实例化一次的类.Singleton通常被用来代表那些本质上唯一的系统组件,如窗口管理器或者文件系统.使类称为Singleton会使它的客户端调试变的十分困难,因为无法给S ...

  9. UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 19: ordinal not in range(128)

    解决方案: 1: 在网上找到的解决方案是: 在调用import matplotlib.pyplot as plt前 import sys sys.setdefaultencoding(“gbk”) 让 ...

  10. 浅谈javascript的运行机制

    积累一下这几天学的,记录一下: 一.为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程 ...