Codeforces 851D Arpa and a list of numbers (枚举+分段)
来源:互联网 发布:雷电网络 价格 编辑:程序博客网 时间:2024/05/20 09:49
题意:给出N个数,删除一个数的花费是X,改变一个数从num变成num+1的花费是Y,问将整个序列的Gcd改成不是1的最小花费。
思路:首先,答案的gcd肯定是素数,素数的倍数是没有意义的, 素数的倍数可以, 那这个素数肯定可以,其次,你知道了答案gcd, 整个数列的最小费用就知道了, 直接比较删除跟取余之后+1的最小值就好了(但这题利用不了这个性质),这题的做法就是, 枚举素数,然后分段, 对g*i到g*(i+1)的花费进行统一计算,每次+=g,复杂度很有保证的,而且这一段区间里的性质(gcd)是一样的,所以每一段很好处理,前缀一下就是O1的,这里mengxiang000讲的比较好
我们知道,Gcd的结果是素数是最好的,所以我们首先筛出素数,1e6内的素数个数约为8w(8e4)个。
然后考虑对应数字是删除还是增添。很显然我们这里可以Dp去做,但是时间复杂度很爆炸,所以考虑X和Y两种操作之间的关系。
①不难想到,如果X<Y的话,我们就不用进行Y操作了。
②所以我们设定move=X/Y表示我们最多对一个数进行增添数字的次数,如果超过了这个次数,我们不如将其删除来的划算。
接下来考虑如何计算结果。首先我们肯定要O(8e4)去枚举答案,接下来考虑,既然我们已经知道了move这个信息,那么对于当前枚举的素数p,我们有一个区间【p,2p】的话,我们肯定能够通过move这个信息找到区间的一个分界点,使得【p~分界点】的数我们都将其删除,使得【分界点~2p】的数字都增添变成2p.
那么这里我们只要枚举出来一个素数p,然后每一次计算之后将区间移动p个长度即可。整体时间复杂度O(Len*LogLen)这里Len表示素数的个数。
#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>using namespace std;typedef long long ll;const ll INF = 1e18;const int maxn = 2e6 + 5;int prime[maxn], cnt[maxn], n, a[maxn], pnum, phi[maxn];ll sum[maxn], x, y;bool book[maxn];void init(){ for(int i = 2; i < maxn; i++) { if(!book[i]) { prime[pnum++] = i; phi[i] = i - 1; } for(int j = 0; j < pnum && prime[j]*i < maxn; j++) { book[prime[j]*i] = 1; if(i%prime[j] == 0) { phi[prime[j]*i] = phi[i]*prime[j]; break; } else phi[prime[j]*i] = phi[i]*(prime[j]-1); } }}int main(){ pnum = 0; init(); scanf("%d%lld%lld", &n, &x, &y); int tmp; for(int i = 1; i <= n; i++) { scanf("%d", &tmp); cnt[tmp]++; sum[tmp] += tmp; }// cout << 1 << endl; for(int i = 1; i < maxn; i++) cnt[i] += cnt[i-1], sum[i] += sum[i-1]; int num = x/y; ll ans = INF; for(int i = 0; i < pnum; i++) { ll tmp = 0; for(int j = prime[i]; j < maxn; j += prime[i]) { ll limit = max(j-prime[i]+1, j-num); ll dele = cnt[limit-1] - cnt[j-prime[i]]; ll add = sum[j] - sum[limit-1]; ll addcnt = cnt[j] - cnt[limit-1]; tmp += dele*x; tmp += y*(j*addcnt - add); } ans = min(ans, tmp); } printf("%lld\n", ans); return 0;}
阅读全文
0 0
- Codeforces 851D Arpa and a list of numbers (枚举+分段)
- Codeforces 851D. Arpa and a list of numbers
- Codeforces 432 Div. 2-D-Arpa and a list of numbers(枚举倍数求GCD)
- Codeforces Round #432 (Div. 2) D 850B Arpa and a list of numbers(gcd 枚举)
- Codeforces 851 D. Arpa and a list of numbers(技巧)
- Codeforces 851 D Arpa and a list of numbers(前缀和)
- codeforces 851 D. Arpa and a list of numbers(前缀和+bruteforce)
- Codeforces 851D Arpa and a list of numbers【思维+前缀和】
- Codeforces 851D Arpa and a list of numbers Round #432 (Div. 2
- Codeforces Round #432 (Div. 2) D. Arpa and a list of numbers E. Arpa and a game with Mojtaba
- Codeforces Codeforces Round #432 (Div. 2 D ) Arpa and a list of numbers 爆搜+剪枝
- Codeforces Codeforces Round #432 (Div. 2 D ) Arpa and a list of numbers
- 解题报告:Codeforces Round #432 (Div. 2) D. Arpa and a list of numbers 暴力
- Codeforces Round #432 -思维&素数筛魔改-D-Arpa and a list of numbers
- codeforces 850B Arpa and a list of numbers
- Codeforces Round #432 B. Arpa and a list of numbers
- codeforces 580B Arpa and a list of numbers 前缀和+思维+分块 (调和级数)
- CF850B-Arpa and a list of numbers
- ccf 201703-3 Markdown ( java)
- Javascript边框闪烁提示
- Android解析WindowManager(一)WindowManager体系
- java 注解
- bug : Undefined symbols for architecture x86_64 个案分析
- Codeforces 851D Arpa and a list of numbers (枚举+分段)
- jmeter与jenkins的集成
- 接口
- ==和equals http://www.cnblogs.com/dolphin0520/p/3592500.html
- js中preventDefault 与stopPropagation 及 stopImmediatePropagation的区别
- 带权路径长度 层次遍历
- 三个div,一个左浮动,一个有浮动,另外一个不浮动引发的样式问题
- Windows Practice(七)_MFC
- 网络层