Codeforces1699E Three Days Grace【数学】【DP】

分析:

一开始觉得是二分答案,发现行不通之后改为枚举最小值。

现在我将这若干个数分解,假设分解完之后得到的最小值为i,那么我就是要在最小值为i的基础上尽量最小化分解的各数的最大值。

考虑DP:设f[x][i]表示在分解结果最小值大于等于i的情况下,将x分解得到的最大值最小是多少。可以得到如下转移:

f[x][i]=min(f[xi][i],f[x][i+1])where i is a factor of x

或者

f[x][i]=f[x][i+1]i is not xs factor

注意到这样转移状态数太多了,但是我们发现,只有当ix的因子时,f[x][i]的值才会发生变化,所以转移可以进一步优化,只留nlnn个有用的状态。

接着,答案就是对每个枚举的i,求f[a[x]][i]的最大值即可。

这个求最大值的过程如果倒着用可删堆维护会爆空间,所以考虑正着来。先倒着预处理出来i等于多少时,f[x][i]会发生变化就行了。(参考我代码里的update部分)

代码:

复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 1050000;
 5 const int maxm = 5050000;
 6 
 7 int n,m;
 8 int a[maxn];
 9 int suf[maxm];
10 int tab[maxm];
11 int update[maxm];
12 
13 struct Priority_Queue{
14     priority_queue<int,vector<int>,less<int> > pq,del;
15     void Push(int now){pq.push(now);}
16     void Del(int now){del.push(now);}
17     int Top(){
18     while(!del.empty() && pq.top() == del.top()){
19         pq.pop();
20         del.pop();
21     }
22     return pq.top();
23     }
24     void clear(){
25     while(!pq.empty()) pq.pop();
26     while(!del.empty()) del.pop();
27     }
28 }Q;
29 
30 int main(){
31     int t; scanf("%d",&t);
32     while(t--){
33     scanf("%d%d",&n,&m);
34     int minn = 1e9,maxx = 0;
35     Q.clear();
36     for(int i=1;i<=n;i++) {
37         scanf("%d",&a[i]);
38         minn = min(minn,a[i]);
39         maxx = max(maxx,a[i]);
40     }
41     for(int i=1;i<=maxx;i++){
42         suf[i] = i;
43         tab[i] = 0;
44         update[i] = 0;
45     }
46     for(int i=1;i<=n;i++) tab[a[i]]=1;
47     int ans = 1e9;
48     for(int i=maxx;i>=2;i--){
49         for(int j=i;1ll*j*i<=maxx;j++){
50         if(tab[i*j]) update[i+1] = max(update[i+1],suf[i*j]);
51         suf[i*j] = min(suf[i*j],suf[j]);
52         }
53     }
54     for(int i=1;i<=maxx;i++){
55         if(tab[i]){
56         update[1] = max(update[1],suf[i]);
57         }
58     }
59     int tot = 0;
60     for(int i=1;i<=minn;i++){
61         tot = max(tot,update[i]);
62         ans = min(ans,tot-i);
63     }
64     printf("%d\n",ans);
65     }
66 }
复制代码

 

posted @   menhera  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示