1 条题解
-
0
自动搬运
来自洛谷,原作者为

nofind
苟到省选退役的蒟蒻搬运于
2025-08-24 22:15:00,当前版本为作者最后更新于2020-01-01 19:53:07,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题意
我自闭了,连蓝题都不会了,还得看题解。
以下是我理解的官方做法,献给给广大没看懂官方题解的神仙们。作者蒟蒻,如果有什么不对的地方请指出。
观察题目的限制,发现是一个的形式,因此我们可以考虑每个质数。
对于每个质数,我们求出一个串,其中第位为则表示存在一个数,它分解后这个质因子的次幂为。特殊地,如果一个数不含这个质因子,那么第位为。的次幂的上界很小,时最大,才级别,因此是开得下的。
现在我们考虑通过题中的操作使得相同的过程:
对于每个质数,显然只有所有分解后的的次幂相同才会满足条件。先假设我们要将所有的中的次幂都消成。
此时,我们要对的状态求出一个最小的集合,满足将这个集合内的数任意相加可以拼出的状态中所有的位置。
就拿官方题解里的例子吧:
对于,在位上是(注意我们是从右向左从零开始数的),于是,因为我们可以通过拼出所有的数。(,,,,)此时我们在时操作分解后的次幂为的位置,在时操作分解后的次幂为的位置,在时操作分解后的次幂为的位置,那么所有的数中的次幂都为。
那么我们就设表示状态的答案,我们可以求出。
但是包含的状态(即是的子集)的答案也可以更新(能拼出就能拼出),我们再枚举每个状态,更新它的子集即可。
现在考虑我们不把所有的中的的次幂消成的情况。
这时候需要满足该状态最低位(即第位)不为,因为为的话就说明有一个数根本就没有这个质因子,那肯定要全消完。
那么我们保留就相当于这个状态的答案,还是拿之前的那个举例:
,在位上是。 我们现在保留,也就是我们要找最小的集合,使其能拼成,那么对应的状态就是。由衷地感叹:这题的确是道思维好题。
code(真·抄的官方题解):
#include<bits/stdc++.h> using namespace std; const int maxn=1e6+10; const int maxm=20; int n,ans; int a[maxn],f[1<<maxm],state[1<<maxm],cnt[1<<maxm]; bool vis[maxn]; vector<int>prime; inline void pre_work() { vis[1]=1; for(int i=2;i<=1000000;i++) { if(!vis[i])prime.push_back(i); for(unsigned int j=0;j<prime.size()&&i*prime[j]<=1000000;j++) { vis[i*prime[j]]=1; if(i%prime[j]==0)break; } } } void dfs(int dep,int now,int s) { f[s]=min(f[s],dep-1); if(dep>5)return; for(int i=now;i<=20;i++)dfs(dep+1,i,(s|(s<<i))&((1<<20)-1)); } int main() { pre_work(); scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); memset(f,0x3f,sizeof(f)); dfs(1,1,1); for(int s=(1<<20)-1;s;s--) for(int j=1;j<=20;j++) if(!((s>>(j-1))&1))f[s]=min(f[s],f[s|(1<<(j-1))]); for(int s=1;s<(1<<20);s++)if(!(s&1))f[s]=min(f[s],f[s>>1]); for(int i=1;i<=n;i++) { int tmp=a[i]; for(unsigned int j=0;j<prime.size()&&prime[j]*prime[j]<=tmp;j++) { if(tmp%prime[j])continue; int k=0; while(tmp%prime[j]==0)k++,tmp/=prime[j]; state[prime[j]]|=1<<k;cnt[prime[j]]++; } if(tmp>1)cnt[tmp]++,state[tmp]|=2; } for(int i=2;i<=1000000;i++) { if(cnt[i]!=n)state[i]|=1; ans+=f[state[i]]; } printf("%d",ans); return 0; }
- 1
信息
- ID
- 4798
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者