codeforces 851D Arpa and a list of numbers

目录

  • codeforces 851D Arpa and a list of numbers
  • 题意
  • 题解
  • Code

codeforces 851D Arpa and a list of numbers

题目传送门

题意

给出\(n\)个数,有两种操作:
1.将一个数从数列中删除,代价为\(x\)。
2.将一个数加1,代价为\(y\)。
询问最少花费多少的代价能够使数列中所有数的\(Gcd\)不为1。
\((1 \leq n \leq 5 \cdot 10^5 , 1 \leq x,y \leq 10^9 , 1 \leq a_i \leq 10^5)\)

题解

emm...这个题目似乎无论是CF上的题解还是各种网上的题解,都是那种利用\(x\)和\(y\)之间的关系来求每个数最优的操作代价。但似乎这个题目还有一个乱搞的做法。。
首先我们肯定想到的是枚举\(1~1e6\)之内的所有素数,然后\(Check\)的贪心的进行选择(正解也是给予这个的)。但是这样的复杂度我们是接受不了的,于是我们就会不由自主地进行乱搞想更加优越的做法。首先我们会发现,无论怎样,让这所有的数的\(Gcd\)等于2似乎是个不错的选择,因为这样最劣的情况也只会对\(n\)个元素进行修改,所以我们刚开始的时候先\(Check\)一下2,作为当前最优的答案。然后由于复杂度的原因,我们不能枚举完所有的素数,那么怎么办?那我们就假装这个答案一定会是某个质因数,并且这个质因数在原来序列中出现过若干次,而出现的次数越多,那么作为最优答案的可能性也越大。这是为什么呢?我也不知道。。我们基于这个似乎不正确的结论,就可以贪心的进行\(Check\)了。先对于每一个数进行分解质因数,然后贪心的从出现次数由高到低进行枚举质因数进行\(Check\),大概\(Check\)个十多个就行了,这样我们至少就可以过了很多的数据了。至于为什么这个乱搞做法是正确的。。信息竞赛不需要证明。。只要觉得对就行了。。

啊啊啊哪个dalao来叉掉我啊,或者帮我证明一下啊。。。(逃

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+500;
vector<int>pri;
int n,x,y;
ll res=2e18;
int a[N];
struct Cnt {
  int idx,cnt;
  bool operator < (const Cnt &rhs) const {
    return cnt>rhs.cnt;
  }
}C[2000005];

void Get(int x) {
  int c=x;
  for(int i=2;i*i<=c;i++) {
    if(c%i==0) C[i].cnt++;
    while(c%i==0) c/=i;
  }
  if(c>1) C[c].cnt++;
}

void Check(int G) {
  ll ans=0;
  for(int i=1;i<=n;i++) {
    if(a[i]%G==0) continue;
    if(x<=y) {
      ans+=1ll*x;
    }
    else {
      int s=a[i]%G;
      s=G-s;
      ans+=min(1ll*s*y,1ll*x);
    }
  }
  res=min(res,ans);
}

int main() {
  scanf("%d%d%d",&n,&x,&y);
  int Mx=0;
  for(int i=1;i<=1000000;i++) C[i].idx=i,C[i].cnt=0;
  for(int i=1;i<=n;i++) {
    scanf("%d",&a[i]);
    Get(a[i]);
  }
  Check(2);
  sort(C+1,C+1000001);
  vector<int>tmp;
  tmp.clear();
  for(int i=1;i<=10;i++) {
    if(C[i].cnt) tmp.push_back(C[i].idx);
    else break;
  }
  for(int i=0;i<(int)tmp.size();i++) {
    Check(tmp[i]);
  }
  printf("%lld\n",res);
  return 0;
}

原文地址:https://www.cnblogs.com/Apocrypha/p/9721270.html

时间: 2024-10-08 01:18:06

codeforces 851D Arpa and a list of numbers的相关文章

【Codeforces 851D Arpa and a list of numbers】

Arpa的数列要根据GCD变成好数列. ·英文题,述大意:      给出一个长度为n(n<=5000000)的序列,其中的元素a[i]<=106,然后输入两个数x,y(x,y<=109)现在有两种操作:①支付x的代价删除一个数.②支付y的代价将一个数加1.题目要求支付最少的代价,使得原序列所有元素的GCD不为1. ·分析:      GCD不为1?那么就是说每个数至少有一个共同的非1因子.使所有数拥有同一个因子一定比使它们拥有两个相同因子容易,所以题目其实要求我们完成这个任务:对于某个

Codeforces 741B Arpa&#39;s weak amphitheater and Mehrdad&#39;s valuable Hoses

[题目链接] http://codeforces.com/problemset/problem/741/B [题目大意] 给出一张图,所有连通块构成分组,每个点有价值和代价, 要么选择整个连通块,要么只能在连通块中选择一个,或者不选,为最大价值 [题解] 首先我们用并查集求出连通块,然后对连通块进行分组背包即可. [代码] #include <cstdio> #include <vector> #include <algorithm> #include <cstr

codeforces 742D Arpa&#39;s weak amphitheater and Mehrdad&#39;s valuable Hoses ——(01背包变形)

题意:给你若干个集合,每个集合内的物品要么选任意一个,要么所有都选,求最后在背包能容纳的范围下最大的价值. 分析:对于每个并查集,从上到下滚动维护即可,其实就是一个01背包= =. 代码如下: 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include <vector> 5 using namespace std; 6 const int N = 1000 + 5;

构造 Codeforces Round #107 (Div. 2) B. Phone Numbers

题目传送门 1 /* 2 构造:结构体排个序,写的有些啰嗦,主要想用用流,少些了判断条件WA好几次:( 3 */ 4 #include <cstdio> 5 #include <algorithm> 6 #include <cstring> 7 #include <cmath> 8 #include <vector> 9 #include <map> 10 #include <iostream> 11 #include &

D. Arpa and a list of numbers Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017)

http://codeforces.com/contest/851/problem/D 分区间操作 1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <time.h> 6 #include <string> 7 #include <set> 8 #include <map> 9

Codeforces Round #432 (Div. 2) D. Arpa and a list of numbers(暴力)

枚举质数,判断是否超过临界值.临界值就是将不是因子中不含这个素数的数的个数乘以x和y的较小值,是否小于当前最小值. #include <algorithm> #include <cstdio> #include <cstring> #include <iostream> #define Max 1000001 #define MAXN 500005 #define MAXNUM 1000005 #define MOD 100000000 #define ri

Codeforces 914 C Travelling Salesman and Special Numbers

Discription The Travelling Salesman spends a lot of time travelling so he tends to get bored. To pass time, he likes to perform operations on numbers. One such operation is to take a positive integer x and reduce it to the number of bits set to 1 in

[Codeforces 850C]Arpa and a game with Mojtaba

Description 题库链接 两个人 Van♂ 游戏.给出 \(n\) 个正整数 \(a_i\) .两人轮流操作,每次选出一个素数 \(p\) 和一个幂数 \(k\) ,选择的前提为该 \(n\) 个数中有 \(p^k\) 的倍数.接着将所有的 \(p^k\) 的倍数除以 \(p^k\) .变成新的序列,继续操作.不能操作者为败,问先手是否必胜. \(1\leq 100\leq n,1\leq a_i\leq 10^9\) Solution 首先显然的是不同的素数间是不会互相影响的.显然这个

CodeForces 742B Arpa’s obvious problem and Mehrdad’s terrible solution (暴力枚举)

题意:求定 n 个数,求有多少对数满足,ai^bi = x. 析:暴力枚举就行,n的复杂度. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream> #include <c