CF1497 E2. Square-free division (hard version)

Problem - E2 - Codeforces

 

题意:

有n个正整数,你至多可以把其中k个修改为任意的正整数

你需要把这n个数划分为若干个连续的段,满足每一段的任意两个数的乘积都不是完全平方数

问最少划分为多少段

 

任意两个数的乘积都不是完全平方数

等价于

把区间内的数质因子分解,每个质因子的指数对2取模,任意两个数的结果都是不同的。

因为可以修改为任意的正整数,所以相当于每个区间内质因子分解指数对2取模的结果至多有k个位置可以与区间内前面的数相同

设dp[i][j]表示前i个数至多修改了j个位置的最少划分段数

枚举最后一段修改了p个位置,假设这最后一段是区间[x,i],那么dp[i][j]可以用dp[x-1][j-p]+1更新

就剩下x怎么求了

预处理le[i][j]表示区间[L,i]至多修改j个数,满足要求的最小的L

这个可以先枚举j,对于每个j用双指针的方法解决

 

复制代码
#include<bits/stdc++.h>

using namespace std;

#define N 200004

int dp[N][21],le[N][21]; 
int cnt[10000001];
int a[N];

int main()
{
    int T,n,k,x,y,l;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;++i) 
        {
            scanf("%d",&a[i]);
             x=1;
            for(int j=2;j*j<=a[i];++j)
                 if(!(a[i]%j))
                {
                    y=0;
                    while(!(a[i]%j))
                    {
                        ++y;
                        a[i]/=j;
                    }
                    if(y&1) x*=j;
                 }
             a[i]*=x;
        }
        for(int i=0;i<=k;++i)
        {
            x=0;
            l=1;
            for(int r=1;r<=n;++r)
             {
                 cnt[a[r]]++;
                 if(cnt[a[r]]!=1) ++x;
                while(x>i)
                {
                    cnt[a[l]]--;
                    if(cnt[a[l]]) --x;
                    ++l; 
                }
                le[r][i]=l;
             }
            while(l<=n) cnt[a[l++]]--;
        }
        for(int i=1;i<=n;++i)
            for(int j=0;j<=k;++j)
                dp[i][j]=n;
        for(int i=1;i<=n;++i)
            for(int j=0;j<=k;++j)
                for(int p=0;p<=j;++p)
                    dp[i][j]=min(dp[i][j],dp[le[i][p]-1][j-p]+1);
        printf("%d\n",dp[n][k]);
    }
}
复制代码

 

posted @   TRTTG  阅读(139)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示