P7091 数上的树
首先将 \(n\) 分解质因数,用 DFS 求出 \(n\) 的所有因数,记为 \(d_1,d_2,\cdots,d_c\),跑一遍反素数那题的代码可知 \(c\leq 23327\)(
设 \(f_i\) 表示根节点为 \(d_i\) 时最小值。
显然,局部最优值可以保证整体最优值,且转移无后效性,即求 \(f_i\) 时不会影响 \(f_j\ (d_j<d_i)\),故答案可以用树形 DP 求出,将所有因数排序后可以转化为序列上的 DP。
对于不能出现在树上的 \(d_i\) 直接 skip 即可。
设 \(g_i\) 表示 \(d_i\) 所含有的质因子个数。For example,\(12=2\times 2\times 3\),所以 \(12\) 有 \(3\) 个质因子。在本题中,\(g_{i}\) 也表示以 \(d_i\) 为根的子树的节点个数,不难发现其为定值。
假设当前转移 \(f_i\) 决策点为 \(j,k\ (d_j\times d_k=d_i)\),那么对于 \(d_j\) 和 \(d_k\) 子树内两两组合出的 pairs 的贡献可以直接由 \(f_j+f_k\) 推得,剩下来只有两种情况:
- Case 1:\(d_j\) 和 \(d_k\) 子树内各一个节点组合出的 pairs。因为它们的 LCA 是 \(d_i\),且共有 \(g_j\times g_k\) 对 pairs,故贡献为 \(g_j\times g_k\times d_i\)。
- Case 2:\(d_i\) 和任意一个节点组合出的 pairs。显然贡献为 \(g_i\times d_i\)。
转移方程:
\]
,其中 \(g_i=g_j+g_k+1\) 可以在 DP 时一并求出。
这样子搞是 \(\mathcal O(c^3)\) 的,显然无法接受。
- 剪枝 1:在枚举内层循环 \(j\) 时发现 \(k\) 有单调性,所以直接用 pointer 代替 \(k\) 即可。这样时间复杂度降为了 \(\mathcal O(c^2)\)。
- 剪枝 2:当 \(j>k\) 时直接 break,减小常数。
综上,我们有了一个 \({\mathcal O}(\sqrt n+m\log c+c^2)\) 的算法(分解质因数 + 处理限制需要二分查找 + DP),代码如下:
ll n,m,num[N],f[N];
ll cnt,pr[N],c[N],tot;
ll fc[N],il[N],d;
map <ll,int> isp;
void dfs(int pos,ll prod){
if(pos>cnt){
if(prod>1)fc[++d]=prod;
return;
} for(int i=0;i<=c[pos];i++)dfs(pos+1,prod),prod*=pr[pos];
}
int main(){
cin>>n>>m;
// factor
ll tmp=n;
for(ll i=2;i*i<=n;i++)
if(n%i==0){
pr[++cnt]=i,isp[i]=1;
while(n%i==0)c[cnt]++,tot++,n/=i;
}
if(n>1)pr[++cnt]=n,tot++,c[cnt]=1,isp[n]=1;
n=tmp;
// find factors
dfs(1,1);
sort(fc+1,fc+d+1);
// limit
for(int i=1;i<=m;i++){
ll val=read();
int pos=lower_bound(fc+1,fc+d+1,val)-fc;
if(pos<=d&&fc[pos]==val)il[pos]=1; // 表示 pos 不能出现
}
// dp
for(int i=1;i<=d;i++){
if(il[i])continue;
if(isp[fc[i]]){
num[i]=1,f[i]=fc[i];
continue;
} il[i]=1,f[i]=inf; // 如果无法由以前的 j,k 转移得到那么 i 也无法得到
int p=i-1;
for(int j=1;j<i;j++){
if(fc[i]%fc[j])continue;
while(fc[p]>fc[i]/fc[j])p--;
if(j>p)break;
if(!il[j]&&!il[p])f[i]=min(f[i],f[j]+f[p]+num[j]*num[p]*fc[i]+(num[i]=num[j]+num[p]+1)*fc[i]),il[i]=0;
}
} if(il[d])puts("-1");
else cout<<(ll)f[d]<<endl;
return 0;
}
P7091 数上的树的更多相关文章
- [Swust OJ 746]--点在线上(线段树解法及巧解)
题目链接:http://acm.swust.edu.cn/problem/746/ Time limit(ms): 1000 Memory limit(kb): 65535 fate是一个数学大牛 ...
- [BJOI2019]删数(线段树)
[BJOI2019]删数(线段树) 题面 洛谷 题解 按照值域我们把每个数的出现次数画成一根根的柱子,然后把柱子向左推导,\([1,n]\)中未被覆盖的区间长度就是答案. 于是问题变成了单点修改值,即 ...
- 【BZOJ4408】[FJOI2016]神秘数(主席树)
[BZOJ4408][FJOI2016]神秘数(主席树) 题面 BZOJ 洛谷 题解 考虑只有一次询问. 我们把所有数排个序,假设当前可以表示出的最大数是\(x\). 起始\(x=0\). 依次考虑接 ...
- BZOJ_2120_数颜色_Set+树状数组+主席树
BZOJ_2120_数颜色_Set+树状数组+主席树 Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L ...
- 【2019.7.25 NOIP模拟赛 T3】树(tree)(dfs序列上开线段树)
没有换根操作 考虑如果没有换根操作,我们该怎么做. 我们可以求出原树的\(dfs\)序列,然后开线段树维护. 对于修改操作,我们可以倍增求\(LCA\),然后在线段树上修改子树内的值. 对于询问操作, ...
- P3939 数颜色 线段树动态开点
P3939 数颜色 线段树动态开点 luogu P3939 水.直接对每种颜色开个权值线段树即可,注意动态开点. #include <cstdio> #include <algori ...
- Jmeter任在运行,线程数上不去
问题 jmeter在运行,但是线程数上不去(本来模型设计了100个总线程,但运行时线程只能上到5,根据图上观察总共也只能运行5个线程) 之前更新了random csv插件 解决办法 查看jmeter. ...
- [BZOJ4408&&BZOJ4299][FJOI2016 && Codechef]神秘数&&FRBSUM(主席树)
4299: Codechef FRBSUM Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 550 Solved: 351[Submit][Statu ...
- BZOJ2120 数颜色(树套树)
B. 数颜色 题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令:1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色 ...
随机推荐
- python web1
***本篇中的测试均需要使用python3完成. 攻击以下面脚本运作的服务器. 针对脚本的代码逻辑,写出生成利用任意代码执行漏洞的恶意序列的脚本: 打开攻击机端口, 将生成的东西输入网页cookie: ...
- Java:ConcurrentHashMap类小记-2(JDK7)
Java:ConcurrentHashMap类小记-2(JDK7) 对 Java 中的 ConcurrentHashMap类,做一个微不足道的小小小小记,分三篇博客: Java:ConcurrentH ...
- Noip模拟53 2021.9.14
T1 ZYB和售货机 首先这道题有两种做法. 一种是发现每个点都可以先被取到只剩一个,只要收益大于$0$ 然后发现建一个$i->f[i]$的图时出现环,要把它去掉, 那么跑一个$tarjan$枚 ...
- STM32必学的时钟系统
STM32的时钟系统 相较于51单片机,stm32的时钟系统可以说是非常复杂了,我们现在看下面的一张图: 上图说明了时钟的走向,是从左至右的从时钟源一步步的分配给外设时钟.需要注意的是,上图左侧一 ...
- shell 匿名管道和命名管道
管道的特点:如果管道中没有数据,那么取管道数据的操作就会滞留,直到管道内进入数据,然后读出后才会终止这一操作:同理,写入管道的操作如果没有读取管道的操作,这一动作也会滞留. 1,匿名管道 匿名管道使用 ...
- Java RMI学习与解读(三)
Java RMI学习与解读(三) 写在前面 接下来这篇就是最感兴趣的Attack RMI部分了. 前面也说过,RMI的通信过程会用到反序列化,那么针对于RMI的三个角色: Server/Regisrt ...
- 你们不要再吵了! Java只有值传递..
写在前边 上次聊到Java8新特性 lambda时,有小伙伴在评论区提及到了lambda对于局部变量的引用,补充着博客的时候,知识点一发散就有了这篇对于值传递还是引用传递的思考.关于这个问题为何会有如 ...
- 阿里云ECI如何6秒扩容3000容器实例?
引言 根据最新CNCF报告,有超过90%的用户在生产环境使用容器,并且有超过80%的用户通过Kubernetes管理容器.是不是我们的生产环境上了K8s就完美解决了应用部署的问题?IT界有句俗语,没有 ...
- VLAN技术 & ACL访问控制
VLAN介绍与配置 VLAN概述 交换网络中的问题 VLAN(Virtual Local Area Network) 在物理网络上划分出逻辑网 ,对应OS模型第二层 VLAN划分不受端口物理位置限制, ...
- 学习JS的第三天
一.逻辑分支(续) 1.三目运算符:条件运算符 a>b?c:d;表达式1?表达式2:表达式3; 根据表达式1执行的结果,来决定执行表达式2还是表达式3 表达式1结果是true执行表达式2,最终返 ...