codeforces1497 E. Square-free division(数学+dp)

开学了,感觉没时间打cf了,上课听不懂,而且一直在忙转班的事情~~ 下周就要回学校了开心

昨天卡C题太久了,一直在想lcm的性质,还好最后回头了,当成构造题做了,瞎搞了搞就出来了,然后看D,由于没有看榜就硬着头皮看D发下没思路看下榜单发下都在搞E,然后转头搞E,忘了完全平方的性质就GG了~


E1. Square-free division (easy version)

不难知道x=p1α1p2α2…pnαnx=p_1^{\alpha_1}p_2^{\alpha_2}\dots p_n^{\alpha_n}x=p1α1p2α2pnαny=p1β1p2β2…pmβmy=p_1^{\beta_1}p_2^{\beta_2}\dots p_m^{\beta_m}y=p1β1p2β2pmβm
设:
ax=p1α1%2p2α2%2…pnαn%2a_x=p_1^{\alpha_1\%2}p_2^{\alpha_2\%2}\dots p_n^{\alpha_n\%2}ax=p1α1%2p2α2%2pnαn%2ay=p1β1%2p2β2%2…pmβm%2a_y=p_1^{\beta_1\%2}p_2^{\beta_2\%2}\dots p_m^{\beta_m\%2}ay=p1β1%2p2β2%2pmβm%2
如果xyxyxy是完全平方数,一定有ax=aya_x=a_yax=ay,于是开个数组,贪心的选即可。

时间复杂度O(namax⁡+n)O(n\sqrt{a_{\max}}+n)O(namax+n)
裸的分解质因数TLE一个点,加了个优化(质数直接不分解)然后过了,其实感觉记忆化一下应该也能过。

// 1996 ms
#include<iostream>
using namespace std;
constexpr int N=200010;
int n,k,a[N],pre[10000010];
int prime[10000010],cnt;
bool is[10000010];
void init(int n)//筛质数
{for(int i=2;i<=n;i++){if(!is[i]) prime[++cnt]=i;for(int j=1;prime[j]<=n/i;j++){is[prime[j]*i]=1;if(i%prime[j]==0) break;}}
}
int main()
{ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int T=1;cin>>T;init(10000000);while(T--){cin>>n>>k;for(int i=1;i<=n;i++){a[i]=1;int x;cin>>x;if(!is[x]) {a[i]=x;continue;}//小优化for(int j=2;j<=x/j;j++)if(x%j==0){int s=0;while(x%j==0) x/=j,s++;if(s&1) a[i]*=j; }if(x>1) a[i]*=x;}int last=0,res=0;for(int i=1;i<=n;i++){if(pre[a[i]]>=last){for(int j=last;j<i;j++) pre[a[j]]=0;res++;last=i;}pre[a[i]]=i;}for(int i=1;i<=n;i++) pre[a[i]]=0;cout<<res<<'\n';}return 0;
}

其实感觉上述代码仍然能被卡TEL,时间复杂度主要在求xxxaxa_xax上,学习了Heltion的代码,发下可以在筛法中做文章: 设ax=f(x)a_x=f(x)ax=f(x)

如果fi%pj=0f_i\%p_j=0fi%pj=0说明fif_ifi里面有一个pjp_jpjfpj×if_{p_j×i}fpj×i则有两个pjp_jpj,于是fpj×i=fi/pjf_{p_j×i}=f_i/p_jfpj×i=fi/pj
如果fi%pj≠0f_i\%p_j\ne0fi%pj=0说明fif_ifi里面没有pjp_jpj,于是fpj×i=fi×pjf_{p_j×i}=f_i×p_jfpj×i=fi×pj
按照上述递推即可。
时间复杂度O(amax⁡+n)O(a_{\max}+n)O(amax+n)

//311 ms
#include<iostream>
using namespace std;
constexpr int N=200010;
int n,k;
int a[N];
int pre[10000010];
int prime[10000010],cnt;
bool is[10000010];
int f[10000010];
void init(int n)
{f[1]=1;for(int i=2;i<=n;i++){if(!is[i]) prime[++cnt]=i,f[i]=i;for(int j=1;prime[j]<=n/i;j++){is[prime[j]*i]=1;if(f[i]%prime[j]) f[i*prime[j]]=f[i]*prime[j];elsef[i*prime[j]]=f[i]/prime[j];if(i%prime[j]==0) break;}}
}
int main()
{ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int T=1;cin>>T;init(10000000);while(T--){cin>>n>>k;for(int i=1;i<=n;i++){a[i]=1;int x;cin>>x;a[i]=f[x];}int last=0,res=0;for(int i=1;i<=n;i++){if(pre[a[i]]>=last){for(int j=last;j<i;j++) pre[a[j]]=0;res++;last=i;}pre[a[i]]=i;}for(int i=1;i<=n;i++) pre[a[i]]=0;cout<<res<<'\n';}return 0;
}

E2. Square-free division (hard version)

10710^7107以内质数个数是664579664579664579,不难得出只要你改变一个数,一定能改变成一个数和任意数组的数的积不是完全平方数。

共有26645792^{664579}2664579选择,只要挑一个变成当前没有的即可。

设计dp:
状态表示:fi,jf_{i,j}fi,j表示考虑前iii个数,操作了jjj次分成的最小段数。
状态转移:考虑第iii个数和哪些数划分到一组。

比如最后一组是[L,i][L,i][L,i],表明数组[L,i][L,i][L,i]的数两两相乘不是完全平方数,根据第一问转化后即[L,i][L,i][L,i]的数都不相同。只需要求出需要操作多少次能使得[L,i][L,i][L,i]数都不相同即可。

一个常用的trick就是记录这个数前一个和它相同数的位置prei\text{pre}_iprei,不难得出[L,i][L,i][L,i]操作次数为∑j=Li1(L≤prej≤i)−1\sum_{j=L}^{i}1(L \leq \text{pre}_j\leq i)-1j=Li1(Lpreji)1即可转移。

下面代码(效仿Heltion)的trick非常巧妙,用一个set维pre数组。最后一组为[x+1,i][x+1,i][x+1,i],然后枚举操作次数转移即可。注意边界情况也就是最后一组为[1,i][1,i][1,i]的情况。

#include<set>
#include<iostream>
#include<algorithm>
using namespace std;
constexpr int N=200010;
int n,k;
int a[N];
int pre[N];
int mp[10000010];
int prime[10000010],cnt;
bool is[10000010];
int f[10000010];
int dp[N][22];
void init(int n)
{f[1]=1;for(int i=2;i<=n;i++){if(!is[i]) prime[++cnt]=i,f[i]=i;for(int j=1;prime[j]<=n/i;j++){is[prime[j]*i]=1;if(f[i]%prime[j]) f[i*prime[j]]=f[i]*prime[j];elsef[i*prime[j]]=f[i]/prime[j];if(i%prime[j]==0) break;}}
}
int main()
{ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int T=1;cin>>T;init(10000000);while(T--){cin>>n>>k;for(int i=1;i<=n;i++){cin>>a[i];a[i]=f[a[i]];}for(int i=1;i<=n;i++){pre[i]=mp[a[i]];mp[a[i]]=i;}for(int i=1;i<=n;i++) for(int j=0;j<=k;j++) dp[i][j]=n;dp[0][0]=0;set<int,greater<int>> s;for(int i=1;i<=n;i++){if(pre[i]) s.insert(pre[i]);for(int j=0;j<=k;j++) dp[i][j]=dp[i-1][j]+1;int c=0;for(int x:s){if(c>k) break;for(int j=c;j<=k;j++)dp[i][j]=min(dp[i][j],dp[x][j-c]+1);c++;}if((int)s.size()<=k) dp[i][s.size()]=1;}cout<<*min_element(dp[n],dp[n]+1+k)<<'\n';for(int i=1;i<=n;i++) mp[a[i]]=0;}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318924.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

牛客题霸 [合并二叉树] C++题解/答案

牛客题霸 [合并二叉树] C题解/答案 题目描述 已知两颗二叉树&#xff0c;将它们合并成一颗二叉树。合并规则是&#xff1a;都存在的结点&#xff0c;就将结点值加起来&#xff0c;否则空的位置就由另一个树的结点来代替。例如&#xff1a; 两颗二叉树是: Tree 1 1 / \ 3 2 / …

“校长”潘淳:侠之大者,一蓑烟雨任平生

我是与丁磊、蔡文胜同时代的人&#xff0c;他们都是70后大我两岁。我的经历与爱好与丁磊有丁点接近&#xff0c;但是没他下海走一走的胆识。又或者与蔡文胜一样&#xff0c;也算是国内最早的域名代理商&#xff0c;却又没有投资的勇气。—— 潘淳《IT英雄传》这一期的主角儿是江…

P4922-[MtOI2018]崩坏3?非酋之战!【dp】

正题 题目链接:https://www.luogu.com.cn/problem/P4922 题目大意 题目好长直接放了 在崩坏 3 中有一个叫做天命基地的地方&#xff0c;女武神们将在基地中开派对与敌人们厮杀。 女武神们的攻击力为 atkatkatk&#xff0c;她们将进行资源保卫战&#xff01; 天命基地中有 …

C. Minimum Grid Path(思维)

昨天晚上写的时候看错题了&#xff0c;以为并不是交替走&#xff0c;最后没时间了读了一遍题目发现是交替走&#xff0c;然后就秒了但是已经没时间写了。 其实昨天并不想写&#xff0c;不过看了下D题发现是个数学题&#xff0c;虽然我数学题非常渣渣&#xff0c;但是拿起笔就推…

牛客题霸 [扑克牌顺子] C++题解/答案

管理博文 牛客题霸 [扑克牌顺子] C题解/答案 题目描述 LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张_)…他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿&#xff01;&#x…

微软Cloud+AI本地化社区贡献指南

本文主要介绍微软CloudAI本地化社区&#xff0c;以及通过多种途径贡献本地化的操作指南。什么是本地化社区CloudAI本地化社区是微软技术社区的组成部分之一&#xff0c;负责对微软官方技术文档本地化的支持工作。微软近些年大力拥抱开源&#xff0c;不断在各类技术社区保持与开…

P7581-「RdOI R2」路径权值【长链剖分,dp】

正题 题目链接:https://www.luogu.com.cn/problem/P7581 题目大意 给出nnn个点的有边权有根树&#xff0c;mmm次询问一个节点xxx的所有kkk级儿子两两之间路径长度。 1≤n,m≤1061\leq n,m\leq 10^61≤n,m≤106 解题思路 有根长剖&#xff0c;无根点分治。所以这题应该是长剖…

牛客题霸 [ 未排序数组中累加和为给定值的最长子数组长度] C++题解/答案

牛客题霸 [ 未排序数组中累加和为给定值的最长子数组长度] C题解/答案 题目描述 给定一个无序数组arr, 其中元素可正、可负、可0。给定一个整数k&#xff0c;求arr所有子数组中累加和为k的最长子数组长度 题解&#xff1a; 先求出前缀和 然后用map来记录第i位的前缀和 要找…

「分块」数列分块入门1 – 9

ACM模板 放暑假了&#xff0c;回归&#xff01;&#xff01;&#xff01; 自己不会写暴力&#xff0c;而且好久没写代码了&#xff0c;于是学学分块的优雅暴力~ 「分块入门-LibreOJ」 「分块」数列分块入门1 – 9 by hzwer 数列简单分块问题实际上有三项东西要我们思考&#…

C#:在Task中使用依赖注入的Service/EFContext

dotnet core时代,依赖注入基本已经成为标配了,这就不多说了.前几天在做某个功能的时候遇到在Task中使用EF DbContext的问题,学艺不精的我被困扰了不短的一段时间,于是有了这个文章.先说一下代码结构和场景.首先有一个HouseDbContext,代码大概是下面这样:public class HouseDbCo…

牛客题霸 [ 最长公共前缀] C++题解/答案

牛客题霸 [ 最长公共前缀] C题解/答案 题目描述 编写一个函数来查找字符串数组中的最长公共前缀。 题解&#xff1a; 原本想暴力做&#xff0c;直接多层循环套&#xff0c;发现并不用 注意本题&#xff0c;给出了多组字符串&#xff0c;求它们的最长公共前缀&#xff0c;这…

pkusc2021游记

文章目录Day 0Day 1Day 2Day 3Day 0 车&#xff0c;公交&#xff0c;飞机&#xff0c;公交&#xff0c;车 坐了半天的交通终于到了&#xff0c;整个人都坐的晕乎乎的&#xff0c;然后看了下学校位置吃了饭就没事回酒店了。 Day 1 早上是报道&#xff0c;九点才开始&#xf…

codeforces82 D. Two out of Three(记忆化搜索)

D. Two out of Three 设fi,jf_{i,j}fi,j​表示为当前队伍开头的两个人是i,ji,ji,j时最小代价&#xff0c;分析可知本轮可以选择的方案有 i,ji,ji,j两人&#xff0c;fi,jaiajfj1,j2f_{i,j}a_ia_jf_{j1,j2}fi,j​ai​aj​fj1,j2​i,j1i,j1i,j1两人&#xff0c;fi,jaiaj1fj,j2f_{…

DevOps/.NET 微服务 秋季分享会领优惠门票

参与活动【活动&#xff08;深圳&#xff09;】DevOps/.NET 微服务 秋季分享会&#xff0c;优惠门票等你来领 的以下10位同学微信联系我: geffzhang 领票

bzoj3729-Gty的游戏【Splay,博弈论】

正题 题目链接:https://darkbzoj.tk/problem/3729 题目大意 给出nnn个点的一棵树&#xff0c;第iii个节点上有aia_iai​个石子&#xff0c;然后每次可以选择不超过LLL个石子移动到父节点处。要求支持操作 以一个节点的子树进行博弈是否有先手必胜修改一个节点的石子个数插入…

牛客题霸 [ 求路径] C++题解/答案

牛客题霸 [ 求路径] C题解/答案 题目描述 一个机器人在mn大小的地图的左上角&#xff08;起点&#xff0c;下图中的标记“start"的位置&#xff09;。 机器人每次向下或向右移动。机器人要到达地图的右下角。&#xff08;终点&#xff0c;下图中的标记“Finish"的位…

【.NET Core项目实战-统一认证平台】第七章 网关篇-自定义客户端限流

上篇文章我介绍了如何在网关上增加自定义客户端授权功能&#xff0c;从设计到编码实现&#xff0c;一步一步详细讲解&#xff0c;相信大家也掌握了自定义中间件的开发技巧了&#xff0c;本篇我们将介绍如何实现自定义客户端的限流功能&#xff0c;来进一步完善网关的基础功能。…

codeforces855 C. Helga Hufflepuff‘s Cup(树形dp)

C. Helga Hufflepuff’s Cup 比较经典的树形dp套路。由于题目限制某类点的数量&#xff0c;因而状态需要记录一下子树中该特殊点的数量。 设计dp&#xff1a; fu,j,kf_{u,j,k}fu,j,k​以uuu为根的子树中&#xff0c;选了jjj个特殊值&#xff08;点权K&#xff09;&#xff0c…

牛客题霸 [链表中倒数第k个结点] C++题解/答案

链表中倒数第k个结点 题解&#xff1a; 我们把链表存两份&#xff0c;让其中一个先走k个节点&#xff0c;然后两个链表一起走&#xff0c;直到第一个链表到头&#xff0c;因为两个相差k个节点&#xff0c;所以第二个链表停的位置就是倒数第k个 代码&#xff1a; /* struct …

P3343-[ZJOI2015]地震后的幻想乡【dp,数学期望】

正题 题目链接:https://www.luogu.com.cn/problem/P3343 题目大意 给出nnn个点的一张无向图&#xff0c;每条边被修复的时间是[0,1][0,1][0,1]的一个随机实数&#xff0c;求这张图联通期望时间。 1≤n≤10,m≤n(n−1)21\leq n\leq 10,m\leq \frac{n(n-1)}{2}1≤n≤10,m≤2n(n…