Arpa的数列要根据GCD变成好数列

·英文题,述大意:
      给出一个长度为n(n<=5000000)的序列,其中的元素a[i]<=106,然后输入两个数x,y(x,y<=109)现在有两种操作:①支付x的代价删除一个数。②支付y的代价将一个数加1。题目要求支付最少的代价,使得原序列所有元素的GCD不为1。

·分析:
      GCD不为1?那么就是说每个数至少有一个共同的非1因子。使所有数拥有同一个因子一定比使它们拥有两个相同因子容易,所以题目其实要求我们完成这个任务:对于某个因子a(就是一个数a),若将原序列所有的数,通过上述操作,使得它们都含有a这个因子的代价和为W,求出所有a中W的最小值。

      根据上文结论,一个相同比两个相同容易,所以呢这个最优解的因子x一定是一个素数(如果是合数就拆成两个或两个以上的素数因子了啊)。

      观察数据,考虑怎样的时间复杂度能够承受:
      从这题来看,相比于元素个数5*106,元素的范围106是一个较小的值,这个值有两种时间复杂度思考:一种是O(N),一种是O(NlogN)对吧?对!

      我们来细看每个元素,如果我们当前枚举因子x(即目标是让所有元素都能够被它整除),对于它只有两种选择:(1)删除(2)通过加1操作使它变成最近的那个a的倍数。很明显,我们需要取舍一番。怎样正确而快速地决策呢?

       由于我们已知了x,y。那么一个数加几个1能够满足比删除这个数的代价小呢?当然是最多加[x/y]次啦 ,这里设T=[x/y](向下取整)。所以我们不妨枚举每一个x的倍数区间,下图所示:

那么对于每一个区间里的元素:

如果它向前走T步以内能够到达3*x,那么我们选择加1绝对比删除它的代价小。反之,我们就删除这个数。下面分别计算两种方案下代价:

       ①通过加一操作:(kx-num[i])*y

       ②通过删除操作:x

       因此,推广地说,如果这个区间[(k-1)*x,kx]内有e1个元素选择方案一,e2个元素选择方案二,那么代价W为:

  W=(kx*e1-Sum(num[i]))*x+e2*y(其中,Sum表示一方案的所有元素的和)

      据此,维护两个前缀数组:

      (1)sum[i]: 表示小于i的元素的个数

      (2)tot[i]:  表示小于i的元素的和

然后整个过程就是:预处理素数和前缀和,然后枚举计算每个素数x的最优代价。由于每次区间的长度变化,所以时间复杂度为O(nlogn)   

      代码在这里:    

 #include<stdio.h>
#include<algorithm>
#define ll long long
#define go(i,a,b) for(int i=a;i<=b;i++)
const int N=;int t,prime[N],n,a,sum[N],lim,T;
ll x,y,ans,tot[N];
void Prime()
{
bool no[N]={};lim=;
go(i,,lim){if(!no[i])prime[++t]=i;
go(j,,t)if(1ll*prime[j]*i<=lim){no[prime[j]*i]=;}else break;}
}
int main()
{
scanf("%d%I64d%I64d",&n,&x,&y);T=x/y;
go(i,,n)scanf("%d",&a),sum[a]++,tot[a]+=a;Prime();
go(i,,lim+prime[t])sum[i]+=sum[i-],tot[i]+=tot[i-];ans=1e18;
go(j,,t)
{
int l,r=;ll res=;while(r<=lim)
{
l=r;r+=prime[j];int p=std::max(l,r-T-);
res+=1ll*(sum[p]-sum[l])*x+(1ll*r*(sum[r]-sum[p])-(tot[r]-tot[p]))*y;
if(r>lim)break;
}
ans=std::min(ans,res);
}
printf("%I64d\n",ans);return ;
}//Paul_Guderian

有一天这首歌会变老就像老杨树上的枝芽

可我还会一遍遍歌唱它如同我的生命。————汪峰《我爱你中国》

【Codeforces 851D Arpa and a list of numbers】的更多相关文章

  1. Codeforces 851D Arpa and a list of numbers

    D. Arpa and a list of numbers time limit per test 2 seconds memory limit per test 256 megabytes inpu ...

  2. 【Codeforces Round #476 (Div. 2) [Thanks, Telegram!] C】Greedy Arkady

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 枚举那个人收到了几次糖i. 最好的情况显然是其他人都只收到i-1次糖. 然后这个人刚好多收了一次糖 也即 (i-1)kx + x & ...

  3. 【Codeforces Round #476 (Div. 2) [Thanks, Telegram!] E】Short Code

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 先建立一棵字典树. 显然,某一些节点上会被打上标记. 问题就转化成求所有标记的深度的和的最小值了. (标记可以上移,但是不能在同一位 ...

  4. 【Codeforces Round #476 (Div. 2) [Thanks, Telegram!] D】Single-use Stones

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 设长度为L的所有区间里面,石头的个数的最小值为k 设取到k的区间为l,r 那么k就为最多能通过的青蛙个数. 假设k再大一点.比如为k ...

  5. 【Codeforces Round #476 (Div. 2) [Thanks, Telegram!] A】Paper Airplanes

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 统计每个人需要的sheet个数. 乘上k 然后除p就是需要的pack个数了 [代码] #include <bits/stdc+ ...

  6. 【Codeforces Round #476 (Div. 2) [Thanks, Telegram!] B】Battleship

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 暴力枚举船的左上角. 然后统计每个点被覆盖次数就好. [代码] #include <bits/stdc++.h> #de ...

  7. 【Codeforces Round #431 (Div. 1) D.Shake It!】

    ·最小割和组合数放在了一起,产生了这道题目. 英文题,述大意:     一张初始化为仅有一个起点0,一个终点1和一条边的图.输入n,m表示n次操作(1<=n,m<=50),每次操作是任选一 ...

  8. 【Codeforces AIM Tech Round 4 (Div. 2) C】

    ·将排序限制于子序列中,又可以说明什么呢? C. Sorting by Subsequences ·英文题,述大意:       输入一个长度为n的无重复元素的序列{a1,a2……an}(1<= ...

  9. 【codeforces 415D】Mashmokh and ACM(普通dp)

    [codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...

随机推荐

  1. 201621123043 《Java程序设计》第7周学习总结

    1. 本周学习总结 2.书面作业 1. GUI中的事件处理 1.1 写出事件处理模型中最重要的几个关键词. 事件:用户的操作. 事件源:产生事件的组件. 事件监听程序:对事件进行处理的操作所引发的相关 ...

  2. python的Flask 介绍

    Flask 介绍 知识点 微框架.WSGI.模板引擎概念 使用 Flask 做 web 应用 模板的使用 根据 URL 返回特定网页 实验步骤 1. 什么是 Flask? Flask 是一个 web ...

  3. 在Windows上安装「算法 第四版」组件

    这篇文档将向你介绍如何在Windows系统上安装本书将用到的Java开发环境,同时我们也提供了一个手把手的.使用我们提供的DrJava工具或者用命令行来创建.编译和运行你的第一个Java程序的手册,这 ...

  4. Java并发编程实战 之 线程安全性

    1.什么是线程安全性 当多个线程访问某个类时,不管运行时环境采用何种调用方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全 ...

  5. 12-TypeScript总结

    从前面的文章大家可以看出,TypeScript具有先天的优势,建议前端开发人员使用TypeScript进行开发,提升自己的面向对象开发思想与能力.: 1.微软开源的客户端脚本语言,是JavaScrip ...

  6. javascript递归函数

    递归函数:是指函数直接或间接调用函数本身,则称该函数为递归函数. 这句话理解起来并不难,从概念上出发,给出以下的例子: function foo(){ console.log("函数 foo ...

  7. 深度学习之 GAN 进行 mnist 图片的生成

    深度学习之 GAN 进行 mnist 图片的生成 mport numpy as np import os import codecs import torch from PIL import Imag ...

  8. Docker学习笔记 - Docker的容器

    docker logs  [-f]  [-t]  [--tail]  容器名 -f -t --tail="all" 无参数:返回所有日志 -f 一直跟踪变化并返回 -t 带时间戳返 ...

  9. Linux将端口设置进防火墙的白名单

    1.先检查linux服务器的端口是否被防火墙拦住 `telnet 172.168.1.101 8080后面跟端口号,如果连接上证明是防火墙白名单.如果没有配置 vi /etc/sysconfig/ip ...

  10. vue2与vue1的区别

    在前面的学习过程中我们已经对vue1有了一定的了解,下面我们来学习一下vue2,看一下vue1与vue2有什么区别. 区别1: 在vue2中使用v-for指令时它可以添加重复的内容,就像可以添加相同的 ...