题解 Six(留坑)
考场上搞了个三进制状压,结果正确性假了……
有想到从约数下手,但觉得就光预处理约数复杂度就爆炸就没往这边想……
首先是关于约数个数的证明,再一次感谢战神:
因为 \(n = \prod p_i^{c_i}\) ,最坏情况下 \(p_i=2\) ,这时有 \(\sum c_i \leqslant 50\)
因为 \(num(p_i) \leqslant 6\) ,所以约数个数(大致上) \(\leqslant (\frac{50}{6})^6 \approx 3\times10^5\)
留个坑吧,我那本组合极值(?)呢
事实上我数组只开了 \(1e5\) 也过了
然后考虑爆搜模拟加数过程
发现需要能够判断一对质因子对有没有出现在不同的数中
举个例子,2 3加入6时要判断2和3是不是来自于同一个数
所以再用一个二进制串,每一位代表某对质因子是否在不同的数中出现过
然后这个dfs就很好记忆化了
然而我质因数分解的判断条件i*i<=n忘写等号了……
至于这里的状态数,题解里说“可以证明” \(\leqslant 50000\) 种,然而不会证……
实测数据中状态数最大的一个点有 \(3267\) 种状态
口胡下是因为每个状态要想发生变化必须加入新的质因子,而受质因子个数限制这个过程最多重复6次?不会证……
upd:感谢@Rings(抱歉我不知道您的id……)提供的柿子:这个状态数应该是 \(\sum\limits_{i=1}^6 {6 \choose 2} 2^{i\choose 2} \approx 4 \times 10^4\)
Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long
#define reg register int
#define fir first
#define sec second
#define make make_pair
//#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline ll read() {
ll ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
ll n;
ll h[10];
const ll mod=1e9+7;
namespace force{
ll p[10], c[10], cnt, ans;
ll dp[N];
void init(ll n) {
ll i;
//cout<<2<<endl;
for (i=2; i*i<=n; ++i) {
//cout<<i<<endl;
if (!(n%i)) {
p[++cnt]=i;
//cout<<"add "<<i<<' '<<n/i<<endl;
do {n/=i; ++c[cnt];} while (!(n%i));
}
}
//cout<<1<<endl;
if (n>1) p[++cnt]=n, c[cnt]=1;
//cout<<"cnt: "<<cnt<<endl;
//for (int i=1; i<=cnt; ++i) cout<<p[i]<<' '; cout<<endl;
//for (int i=1; i<=cnt; ++i) cout<<c[i]<<' '; cout<<endl;
}
ll qpow(ll a, ll b) {
ll ans=1;
while (b) {
if (b&1) ans=ans*a%mod;
a=a*a%mod; b>>=1;
}
return ans;
}
void solve() {
init(n);
h[0]=1;
for (int i=1; i<=9; ++i) h[i]=h[i-1]*3;
int t[10], num; ll pi[10];
int lim=h[cnt], lim2=1<<cnt;
//cout<<"lim: "<<lim<<' '<<lim2<<endl;
ll cnt2;
for (int i=1; i<lim2; ++i) {
cnt2=0;
for (int j=0; j<cnt; ++j) if (i&(1<<j)) {
cnt2+=c[j+1]-1;
}
pi[i]=qpow(2, cnt2);
//cout<<"pi: "<<bitset<3>(i)<<' '<<pi[i]<<endl;
}
dp[0]=1;
memset(t, 0, sizeof(t));
for (int s=0; s<lim; ++s) {
num=0;
for (int i=0; i<cnt; ++i) num+=t[i]*h[i];
//cout<<"num: "<<num<<endl;
for (int i=1,tem; i<lim2; ++i) {
tem=0;
for (int j=0; j<cnt; ++j) if (i&(1<<j)) {
if (t[j]==2) goto jump;
else tem+=h[j];
}
if (cnt==2 && t[0]==1 && t[1]==1 && i==3) {
dp[num+tem]=(dp[num+tem]+((dp[num]-dp[1]-dp[3])%mod+mod)%mod*pi[i]%mod)%mod;
}
else dp[num+tem]=(dp[num+tem]+dp[num]*pi[i]%mod)%mod;
jump: ;
}
//cout<<"dp"; for (int i=0; i<cnt; ++i) cout<<t[i]; cout<<": "<<dp[num]<<endl;
if (num) ans=(ans+dp[num])%mod;
++t[0];
for (int i=0; i<cnt; ++i)
if (t[i]>=3) ++t[i+1], t[i]-=3;
else break;
}
printf("%lld\n", ((ans)%mod+mod)%mod);
exit(0);
}
}
namespace task{
ll p[10], c[10], div[N];
int ds[N], pcnt, dcnt, tran[10][10], pr[1<<7];
struct pair_hush{inline size_t operator () (pair<int, int> p) const {return hash<ll>()(1ll*p.fir*p.sec+p.fir);}};
unordered_map<pair<int, int>, ll, pair_hush> mp{5000, pair_hush()};
void dfs1(int u, ll sum, int s) {
//cout<<"dfs1 "<<u<<' '<<sum<<' '<<s<<endl;
if (u>pcnt) {if (sum!=1) div[++dcnt]=sum, ds[dcnt]=s; return ;}
dfs1(u+1, sum, s);
for (reg i=1; i<=c[u]; ++i)
dfs1(u+1, sum*p[u], s|(1<<(u-1)));
}
void init(ll n) {
ll i;
for (i=2; i*i<=n; ++i)
if (!(n%i)) {
p[++pcnt]=i;
do {n/=i; ++c[pcnt];} while (!(n%i));
}
if (n>1) p[++pcnt]=n, c[pcnt]=1;
//cout<<"pcnt: "<<pcnt<<endl;
//cout<<"p: "; for (int i=1; i<=pcnt; ++i) cout<<p[i]<<' '; cout<<endl;
dfs1(1, 1, 0);
//cout<<"dcnt: "<<dcnt<<endl;
//for (int i=1; i<=dcnt; ++i) cout<<div[i]<<' '<<bitset<5>(ds[i])<<endl;
int tot=0;
for (reg i=0; i<pcnt; ++i)
for (reg j=i; j<pcnt; ++j)
tran[i][j]=tran[j][i]=1<<(tot++);
//cout<<"tot: "<<tot<<endl;
int lim=1<<pcnt;
for (reg s=1; s<lim; ++s)
for (reg i=0; i<pcnt; ++i) if (s&(1<<i))
for (reg j=0; j<pcnt; ++j) if (s&(1<<j))
pr[s]|=tran[i][j];
}
ll dfs(int s, int t) {
//cout<<"dfs "<<bitset<5>(s)<<' '<<bitset<5>(t)<<endl;
if (mp.find(make(s, t))!=mp.end()) return mp[make(s, t)];
ll ans=0;
for (int i=1,s2; i<=dcnt; ++i) {
s2=s&ds[i];
if (!(t&pr[s2])) {
s2=0;
for (reg j=0; j<pcnt; ++j) if (ds[i]&(1<<j))
for (reg k=0; k<pcnt; ++k) if (s&(1<<k))
s2|=tran[j][k];
ans=(ans+dfs(s|ds[i], t|s2))%mod;
}
}
//cout<<"return "<<bitset<5>(s)<<' '<<bitset<5>(t)<<' '<<ans+1<<endl;
mp[make(s, t)]=ans+1;
return ans+1;
}
void solve() {
init(n);
printf("%lld\n", dfs(0, 0)-1);
exit(0);
}
}
signed main()
{
n=read();
//force::solve();
task::solve();
return 0;
}
题解 Six(留坑)的更多相关文章
- Codeforces Round #364 (Div. 1)(vp) 没什么题解就留坑待填
我就做了前两题,第一题第一次vp就把我搞自闭跑路了,第二题第二次又把我搞自闭了 A. As Fast As Possible 细节题 #include<cstdio> #include&l ...
- [kuangbin带你飞]专题十一 网络流个人题解(L题留坑)
A - ACM Computer Factory 题目描述:某个工厂可以利用P个部件做一台电脑,有N个加工用的机器,但是每一个机器需要特定的部分才能加工,给你P与N,然后是N行描述机器的最大同时加工数 ...
- 题解 queen(留坑)
传送门 博客园突然打不开了,奇奇怪怪的-- 少写个等号没看出来 nm写反了没看出来 考完5min全拍出来了 手残属性加持 不对拍等于爆零 yysy,我连卢卡斯定理的存在都忘了-- 发现要让一大堆皇后能 ...
- 2.18比赛(T2,T3留坑)
2.18比赛(T2,T3留坑) pdf版题面 pdf版题解 超越一切(ak) [题目描述] 夏洛可得到一个(h+1)×(w+1)的巧克力,这意味着她横着最多可 以切 h 刀,竖着最多可以切 w 刀 她 ...
- CPU虚拟化技术(留坑)
留坑~~~ 不知道这个是这么实现的 CPU虚拟化技术就是单CPU模拟多CPU并行,允许一个平台同时运行多个操作系统,并且应用程序都可以在相互独立的空间内运行而互不影响,从而显著提高计算机的工作效率.虚 ...
- 【留坑】uva12299
这么sb的题本来想练练手记过就是过不了 拍半天也没问题 留坑 哪天有空了去linux下面试试 #include<cstdio> #include<cstring> #inclu ...
- 【问题解决方案】Git bash进入多层子目录问题(通配符问题留坑)
cd进入指定路径下:cd 斜杠 斜杠 方法一: 1- 撇丿,不是"那",盘符前面要加上 / (d盘前面也加,不加也行) 2- 路径名不区分大小写 3- 不用空格 4- 如果目录名中 ...
- 题解 c(留坑)
传送门 这题卡常--而且目前还没有卡过去 首先以原树重心为根,向所有子树重心连边,可以建立一棵点分树 点分树有两个性质: 一个是树高只有log层 另一个是两点在点分树上的lca一定在原树上两点间的树上 ...
- 培训补坑(day7:线段树的区间修改与运用)(day6是测试,测试题解以后补坑QAQ)
补坑咯~ 今天围绕的是一个神奇的数据结构:线段树.(感觉叫做区间树也挺科学的.) 线段树,顾名思义就是用来查找一段区间内的最大值,最小值,区间和等等元素. 那么这个线段树有什么优势呢? 比如我们要多次 ...
随机推荐
- CVE-2017-12615 Tomcat远程代码执行
影响版本: Apache Tomcat 7.0.0 - 7.0.81 ps:安装Tomcat需要安装jdk(JAVA环境) 下面来正经复现,Payload: 利用burpsuite 进行抓包 发送到r ...
- 创建自己的RSA密钥来保护web.config 加密数据库连接字符串
通过创建自己的RSA密钥来保护web.config1创建RSA密钥:C:\Windows\Microsoft.NET\Framework64\v4.0.30319>aspnet_regiis - ...
- Java基础00-继承17
1. 继承 1.1 继承概述 但是我们将相同的类提取出来就会变成这个样子 让他们之间产生一个继承的关系 1.2 继承的好处和弊端 IS-A.HAS-A和USE-A关系 苹果是水果的一种可以使用继承猫是 ...
- [刘阳Java]_大型电商网站架构技术演化历程
今年的双十一已经过去一段,作为技术小咖啡,我们先说一下大型电商网站的特点:高并发,大流量,高可用,海量数据.下面就说说大型网站的架构演化过程,它的技术架构是如何一步步的演化的 1. 早期的网站架构 初 ...
- .net core番外第2篇:Autofac的3种依赖注入方式(构造函数注入、属性注入和方法注入),以及在过滤器里面实现依赖注入
本篇文章接前一篇,建议可以先看前篇文章,再看本文,会有更好的效果. 前一篇跳转链接:https://www.cnblogs.com/weskynet/p/15046999.html 正文: Autof ...
- 让Angular自定义组件支持form表单验证
Angular提供了一套非常强大的表单验证库(vue和react都需要第三方库的支持),可以非常方便简单实现web应用程序中的表单验证功能.但是如何让我们自定义的组件也支持验证呢? 我遇到一个需求是封 ...
- centos7下安装mycat中间件 笔记
1. 下载 # wget http://dl.mycat.org.cn/1.6.7.4/Mycat-server-1.6.7.4-release/Mycat-server-1.6.7.4-releas ...
- 网络损伤仪WANsim的带宽限制功能
带宽限制功能 带宽限制功能是网络损伤仪WANsim的第一项损伤功能.进入WANsim的报文首先会经过报文过滤器的处理,随后,就会进入带宽限制. 点击虚拟链路,就可以进入网络损伤界面,对报文进行带宽限制 ...
- Linux中tomcat随服务器自启动的设置方法
1. cd到rc.local文件所在目录,一般在 /etc/rc.d/目录. 2. 将rc.local下载到本地windows系统中. 3. 编辑rc.local,将要启动的tomcat /bin/ ...
- Python自动化测试面试题-性能篇
目录 Python自动化测试面试题-经验篇 Python自动化测试面试题-用例设计篇 Python自动化测试面试题-Linux篇 Python自动化测试面试题-MySQL篇 Python自动化测试面试 ...