codeforces 851 D. Arpa and a list of numbers(前缀和+bruteforce)
2017-09-05 09:11
447 查看
题目链接
D. Arpa and a list of numbers分析
是我太天真了,暴力枚举素数还是计算还是有问题的,复杂度太高,不过你可以发现只需要再处理一个前缀和就可以了….下面进入正题首先显然可以想到枚举素数,那么最终就是对于每个素数的计算问题了,如果暴力计算的化肯定是要超时的,其实我们可以在O(1) 计算花费.
对于素数 k 来说,不为k 的倍数的数都要加到k 的倍数,所以只需要对每一个倍数区间计算就好,在 [i∗k,(i+1)∗k] 的区间内,显然只有ai+⌊x/y⌋≥(i+1)∗k 的数会加,其余都删除,因此,我们预处理一个前缀和sum 表示到[0,n] 的总个数
(sum[i+⌊x/y⌋−1]−sum[i∗k])∗x, 表示删除的花费,
那么加操作的花费呢?对于在 [i∗k,(i+1)∗k] 的区间内 满 足 ai+⌊x/y⌋≥(i+1)∗k 的数来说,它的花费是((i+1)∗k−ai)∗y,因此所有需要加的数的花费为
∑i=1s((i+1)∗k−ai)∗y=y∗(s(i+1)∗k−∑ai)
因此预处理一个关于ai 值的前缀和就好了,O(1) 计算,总复杂度 nlog(n)
ac code
#include<bits/stdc++.h> #define pb push_back #define mp make_pair #define PI acos(-1) #define fi first #define se second #define INF 0x3f3f3f3f #define INF64 0x3f3f3f3f3f3f3f3f #define random(a,b) ((a)+rand()%((b)-(a)+1)) #define ms(x,v) memset((x),(v),sizeof(x)) #define scint(x) scanf("%d",&x ); #define scf(x) scanf("%lf",&x ); #define eps 1e-10 #define dcmp(x) (fabs(x) < eps? 0:((x) <0?-1:1)) #define lc o<<1 #define rc o<<1|1 using namespace std; typedef long long LL; typedef long double DB; typedef pair<int,int> Pair; const int maxn = 2e6+10; const int MAX_V= 500+10; const int MOD = 998244353; int prime[maxn],cnt; void init(){ cnt =0; memset(prime,0,sizeof(prime)); for(int i = 2 ; i<maxn ; ++i){ if(!prime[i]){ prime[cnt++] = i; } for(int j=0 ; j<cnt && i*prime[j]<maxn ; ++j){ prime[i*prime[j]] = 1; if(i%prime[j] == 0) break; } } } LL a[maxn],p[maxn]; LL sum[maxn]; int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); init(); int n,x,y; ms(a,0); cin>>n>>x>>y; int maxv =0; for(int i=0 ; i<n ; ++i){ int tmp; cin>>tmp;a[tmp]++; maxv = max(maxv,tmp); } sum[0] =0; p[0] =0; for(int i=1 ; i<maxn ; ++i){ sum[i] = sum[i-1] + a[i]; p[i]+= p[i-1] +a[i]*i; } LL ans =1e18; int t = x/y; for(int j =0 ; j<cnt&& prime[j] <= 2*maxv; ++j){ int k = prime[j]; LL res =0; for(int i = k ; i<maxn&&i<=2*maxv; i+=k){ int bound = min(t,k-1); res += (sum[i-bound-1] - sum[i-k])*x; if(res >= ans)break; LL s = sum[i-1] - sum[i-bound-1]; res += (s*i - (p[i-1] - p[i - bound - 1]))*y; } ans = min(res,ans); } std::cout << ans << '\n'; //std::cout << "time "<< clock()/1000 <<"ms"<< '\n'; return 0; }
相关文章推荐
- Codeforces 851 D. Arpa and a list of numbers(技巧)
- Codeforces 850B - Arpa and a list of numbers(前缀和)
- Codeforces 432 Div. 2-D-Arpa and a list of numbers(枚举倍数求GCD)
- 【前缀和】【枚举倍数】 Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017) D. Arpa and a list of numbers
- Codeforces Codeforces Round #432 (Div. 2 D ) Arpa and a list of numbers
- Codeforces 851D Arpa and a list of numbers (枚举+分段)
- Codeforces 851D Arpa and a list of numbers
- 【Codeforces 851D 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
- CF850B-Arpa and a list of numbers
- Codeforces Codeforces Round #432 (Div. 2 D ) Arpa and a list of numbers
- Codeforces Round #432 (Div. 1): B. 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 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 Codeforces Round #432 (Div. 2 D ) Arpa and a list of numbers
- CF_850B Arpa and a list of numbers
- Codeforces Codeforces Round #432 (Div. 2 D ) Arpa and a list of numbers