问题 A: Six

时间限制: 1 Sec  内存限制: 512 MB

题面


题面谢绝公开。

题解


来写一篇正经的题解。

每一个数对于答案的贡献与数本身无关,只与它包含了哪几个质因数有关。

所以考虑二进制记录状态,记忆化搜索。

可以发现,每个数对于答案的贡献与其数值本身无关,只与其所包含的素数集合有关。

举个例子:$6(2^1*3^1),12(2^2*3^1),24(2^3*3^1)$在二进制下可以压成同一个状态,因为他们都只包含{2,3}这个素数集合。

考虑题意所述:新加入的值满足至多与一个已经加入的值不互质。

换一种理解:新加入的值只要与其中两及以上个值不互质就不是合法状态。

所以考虑对这些素数两两配对,记录数对的出现状态。所以压成$2^{21}$个状态,每个状态代表一个数对。(为什么是$21$??$21=C_6^2+6$)

没有理解?举个例子:对于样例,$n=6$,有一种不合法的状态为:${2,3,6}$,当我们加入$6$的时候,它本身包含一个数对${2,3}$,而$2$在已选集合中出现过,$3$在已选集合中某个与$2$出现位置不同的位置出现过,则已选集合在数对${2,3}$对应的二进制下为$1$,此时再加入$6$就不合法了。

总的来讲,我们把$n$的每一个约数都视为一个素数集合,如果当前加入的这个元素有两个或两个以上的素数对在已选集合中的两个及以上集合出现过,则状态不合法。

根据这样来压位存储状态,记忆化搜索一发就完了。

具体实现主要难度在预处理??

代码:

#include<bits/stdc++.h>
#define int long long
#define rint register int
using namespace std;
const int mod=1000000007;
inline void read(int &a)
{
a=0;int b=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')b=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+ch-'0';ch=getchar();}
a=a*b;return ;
}
int n,sum[1<<6|1],prime[100005],t[7],yxs[100005],cnt[1<<6|1];
int pd[7][7],tag[1<<21|1];
struct node{int x,y;};
bool operator < (node A,node B){
return (A.x==B.x)?A.y<B.y:A.x<B.x;
}
map <node,int> mp;
inline void devide1()
{
int lin=n;
for(rint i=2;i<=sqrt(n);++i)
{
if(lin%i==0)
{
prime[++prime[0]]=i;
t[prime[0]]=1<<(prime[0]-1);
while(lin%i==0)lin/=i;
}
}
if(lin!=1)
{
prime[++prime[0]]=lin;
t[prime[0]]=1<<(prime[0]-1);
}
return ;
}
inline void devide2()
{
for(rint i=1;i<=sqrt(n);++i)
{
if(n%i==0)
{
if(i!=1)yxs[++yxs[0]]=i;
if(n/i!=i)yxs[++yxs[0]]=n/i;
}
}
return ;
}
inline void devide3()
{
for(rint i=1,res;i<=yxs[0];++i)
{
res=0;
for(rint j=1;j<=prime[0];++j)
if(yxs[i]%prime[j]==0)res|=t[j];
cnt[res]++;
}
return ;
}
inline void start()
{
devide1();//cout<<1<<endl;
devide2();//cout<<2<<endl;
devide3();//cout<<3<<endl;
pd[1][1]=1<<0,pd[2][2]=1<<1,pd[3][3]=1<<2;
pd[4][4]=1<<3,pd[5][5]=1<<4,pd[6][6]=1<<5;
pd[1][2]=pd[2][1]=1<<6;pd[1][3]=pd[3][1]=1<<7;
pd[1][4]=pd[4][1]=1<<8;pd[1][5]=pd[5][1]=1<<9;
pd[1][6]=pd[6][1]=1<<10;pd[2][3]=pd[3][2]=1<<11;
pd[2][4]=pd[4][2]=1<<12;pd[2][5]=pd[5][2]=1<<13;
pd[2][6]=pd[6][2]=1<<14;pd[3][4]=pd[4][3]=1<<15;
pd[3][5]=pd[5][3]=1<<16;pd[3][6]=pd[6][3]=1<<17;
pd[4][5]=pd[5][4]=1<<18;pd[4][6]=pd[6][4]=1<<19;
pd[5][6]=pd[6][5]=1<<20;
vector <int> v;
for(rint i=1;i<=(1<<prime[0])-1;++i)
{
v.clear();int res=i;
for(rint j=1;j<=prime[0];++j)
if(res&t[j])v.push_back(j);
for(rint j=0;j<v.size();++j)
for(rint k=j;k<v.size();++k)
tag[i]|=pd[v[j]][v[k]];
}
}
inline int dfs(int us,int ng)
{
node lode=(node){us,ng};
if(mp[lode])return mp[lode]%mod;
for(rint i=1;i<=(1<<prime[0])-1;++i)
{
if(tag[i]&ng)continue;
int lin=ng;
for(rint j=1;j<=prime[0];++j)
{
if(!(i&t[j]))continue;
for(rint k=1;k<=prime[0];++k)
{
if(!(us&t[k]))continue;
lin|=pd[j][k];
}
}
mp[lode]=(mp[lode]+cnt[i]*(dfs(us|i,lin)%mod+1))%mod;
}
return mp[lode]%mod;
}
signed main()
{
read(n);start();
printf("%lld\n",dfs(0,0));
return 0;
}

「题解」:$Six$的更多相关文章

  1. 「题解」「美团 CodeM 资格赛」跳格子

    目录 「题解」「美团 CodeM 资格赛」跳格子 题目描述 考场思路 思路分析及正解代码 「题解」「美团 CodeM 资格赛」跳格子 今天真的考自闭了... \(T1\) 花了 \(2h\) 都没有搞 ...

  2. 「题解」「HNOI2013」切糕

    文章目录 「题解」「HNOI2013」切糕 题目描述 思路分析及代码 题目分析 题解及代码 「题解」「HNOI2013」切糕 题目描述 点这里 思路分析及代码 题目分析 这道题的题目可以说得上是史上最 ...

  3. 「题解」JOIOI 王国

    「题解」JOIOI 王国 题目描述 考场思考 正解 题目描述 点这里 考场思考 因为时间不太够了,直接一上来就着手暴力.但是本人太菜,居然暴力爆 000 ,然后当场自闭- 一气之下,发现对 60pts ...

  4. 「题解报告」 P3167 [CQOI2014]通配符匹配

    「题解报告」 P3167 [CQOI2014]通配符匹配 思路 *和?显然无法直接匹配,但是可以发现「通配符个数不超过 \(10\) 」,那么我们可以考虑分段匹配. 我们首先把原字符串分成多个以一个通 ...

  5. Linux 小知识翻译 - 「RAID」

    最近术语「RAID」变得比较有名.「RAID」是指将多个HDD组合起来使用,从而提高存储可靠性的一种技术. 那么,关于 RAID 中的 「RAID 0」「RAID 1」「RAID 5」等各种「RAID ...

  6. 正则表达式从入门到放弃「Java」

    正则表达式能做什么? 正则表达式可以用来搜索.编辑或处理文本. 「都懂它可以处理文本,可到底是怎么回事?」 正则表达式的定义 百度百科:正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特 ...

  7. 「题解」:[loj2763][JOI2013]现代豪宅

    问题 A: 现代豪宅 时间限制: 1 Sec  内存限制: 256 MB 题面 题目描述 (题目译自 $JOI 2013 Final T3$「現代的な屋敷」) 你在某个很大的豪宅里迷路了.这个豪宅由东 ...

  8. Scala 学习(10)之「集合 」

    数组 定长数组 Array:采用()访问,而不是[],下标从 0 开始. val array1 = new Array[String](5) //创建数组 println(array1) //返回数组 ...

  9. JavaScript OOP 之「创建对象」

    工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...

  10. Facebook 发布「流程」

    时不时就会在面试过程中碰到有候选人问 Facebook 是否采用 Scrum 之类的敏捷方法,偶尔也会有中国的朋友问及 Facebook 上线流程.我通常会简单说几句,然后说「如果你真感兴趣的话,去搜 ...

随机推荐

  1. 为什么不能在shell脚本中执行source /etc/profile或者source ~/.bashrc问题?

    执行脚本时,其中的命令是在一个子shell中执行的.子shell继承了父shell的环境变量,但无法修改他们,或者说所做的修改仅对子shell有效.

  2. SCP-Py-001

    项目编号:Py-001 项目等级:Euclid 特殊收容措施: Py-001必须被存储于基金会主站的网络硬盘中,并切断一切与互联网的连接. Py-001突破收容在网络上传播后,一旦在一台计算机上被下载 ...

  3. <Jmeter入门不放弃>之<2.常用功能>

    大家这里参考学习的时候,我就不在这里配截图了,因为需要你打开工具根据文档自己去找,才有印象,大家一定要启动JMeter!跟着理解操作 一.测试计划 用来描述一个性能测试,所有内容都是基于这个计划,这谁 ...

  4. HTML5+CSS3特效设计集锦

    20款CSS3鼠标经过文字背景动画特效 站长之家 -- HTML5特效索引 爱果果h5酷站欣赏  30个酷毙的交互式网站(HTML5+CSS3) 轻松搞定动画!17个有趣实用的CSS 3悬停效果教程 ...

  5. jmeter之-聚合报告&分析结果

    Label:请求的名称 Sample:表示这次测试中一共发了多少个请求 Average:平均响应时间 median:中位数,也就是表示在所有请求响应时间中排在中间的那个响应的时间点,50%line 实 ...

  6. 【Shiro】二、Apache Shiro配置

    1.配置 使用配置获得SecurityManager,SecurityManager是核心,配置好并获取到SecurityManager,Shiro就算正式运行起来了. 两种方式:通过ini文件:通过 ...

  7. java中常用的转义字符(转)

    Java编程中往往需要一些特殊操作,例如空格,换行.或者一些你使用特殊符号的意愿与程序中特殊符号意思冲突的时候,我们不能直接写就需要把这些符号转义,表达你的本意,并与程序中特殊符号做区分,这些都需要转 ...

  8. SqlSession(SqlSessionTemplate类) 实现Mybatis

    yBatis3与spring整合之使用SqlSession(SqlSessionDaoTemplate类) ---------- 注:这是手工编写实现的方式(其实可以直接使用注入映射器的) SqlSe ...

  9. PostgreSQL9.6的新特性并行查询

    PostgreSQL在2016年9月发布了9.6版本,在该版本中新增了并行计算功能,目前PG支持的并行查询主要是顺序扫描(Sequencial Scans),并且支持部分链接查询(join)和聚合(a ...

  10. leetcode的一些贪心题目

    11-盛最多水的容器 思路:定义2个指针分别指向数组的两端,找出两边缘最小的那个,然后乘以两边缘的距离,然后向中间搜索,移动一次算出结果比较取最大的. class Solution { public: ...