Codeforces Round #432 (Div. 2) D 850B Arpa and a list of numbers(gcd 枚举)
2017-09-06 07:24
573 查看
一看到感觉是dp,但是dp也太难了呀,然后就滚了.
gcd的问题很多时候都是枚举,因为gcd其实是很难递推的一个东西,所以观察一下ai的范围,大概也能猜到.
那么我们枚举每一个gcd,当然,是素数啦,然后发现每一个gcd我们数列的值可以O(n)算出来,可是素数有很多,这样不够,那么我们怎么样更快呢,就是可以利用一个区间的思想,假设x/y=delta,也就是说,假设p是gcd的一个倍数,那么在p-delta~p的范围内的数,他们要变成p,而在p-gcd~p-delta-1范围内的数,就是要删除,对吧?所以我们预处理一下,就可以在O(1)内得到要删除的数字数量和要加的数字之和(注意两者不同,要处理两个数组).感觉这里很奇妙的就是以前的前缀和都是以下标来做数组,但是这里直接是以值来做数组,这样好处就是假如用下标,那么要找到是logn,但这里ai小,所以直接用,可以O(1)得到,第一次见呢.
(感觉D题还是太难了,我还是太菜了,写起来真的各种难,留下我丑陋的调试痕迹好了)
gcd的问题很多时候都是枚举,因为gcd其实是很难递推的一个东西,所以观察一下ai的范围,大概也能猜到.
那么我们枚举每一个gcd,当然,是素数啦,然后发现每一个gcd我们数列的值可以O(n)算出来,可是素数有很多,这样不够,那么我们怎么样更快呢,就是可以利用一个区间的思想,假设x/y=delta,也就是说,假设p是gcd的一个倍数,那么在p-delta~p的范围内的数,他们要变成p,而在p-gcd~p-delta-1范围内的数,就是要删除,对吧?所以我们预处理一下,就可以在O(1)内得到要删除的数字数量和要加的数字之和(注意两者不同,要处理两个数组).感觉这里很奇妙的就是以前的前缀和都是以下标来做数组,但是这里直接是以值来做数组,这样好处就是假如用下标,那么要找到是logn,但这里ai小,所以直接用,可以O(1)得到,第一次见呢.
(感觉D题还是太难了,我还是太菜了,写起来真的各种难,留下我丑陋的调试痕迹好了)
/* xzppp */ #include <iostream> #include <vector> #include <cstdio> #include <string.h> #include <algorithm> #include <queue> #include <map> #include <string> #include <cmath> #include <bitset> #include <iomanip> using namespace std; #define FFF freopen("in.txt","r",stdin);freopen("out.txt","w",stdout); #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define MP make_pair #define PB push_back typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int > pii; typedef pair<double,double > pdd; typedef pair<double,int > pdi; const int MAXN = 1e6+17; const int MAXM = 20; const int MAXV = 2*1e3+17; const int INF = 0x7fffffff; const LL INFF = 0x7fffffffffffffff; const int MOD = 1e9+7; LL prime[MAXN]; LL vis[MAXN]; LL cnt; void get(){ memset(vis, 0, sizeof(vis)); cnt=0; for(int i=2;i<MAXN;i++){ if(!vis[i]){ prime[++cnt]=i; for(int j=i+i;j<MAXN;j+=i){ vis[j]=1; } } } } LL a[2*MAXN],c[2*MAXN],tms[2*MAXN],sum[2*MAXN]; int main() { #ifndef ONLINE_JUDGE FFF #endif get(); LL n,x,y,gst= 0 ; cin>>n>>x>>y; for (int i = 0; i < n; ++i) { scanf("%lld",a+i); tms[a[i]]++; sum[a[i]]+=a[i]; gst = max(gst,a[i]); } for (int i = 1; i <= 2*MAXN; ++i) { tms[i]+=tms[i-1]; sum[i]+=sum[i-1]; } LL ans = INFF,delta = x/y,ori = delta; for (int i = 1; i <= cnt; ++i) { //cout<<prime[i]<<endl; if(prime[i]>2*gst) break; LL p = prime[i]; LL del=0,inc=0,sinc=0,temp=0; for (LL j = p; j <= gst+p; j+=p) { if(delta<p-1) { del = tms[j-delta-1] - tms[j-p]; inc = sum[j-1] - sum[j-delta-1]; sinc = tms[j-1] - tms[j-delta-1]; //if(del<0) cout<<j-delta-1<<" asd "<<j-p<<endl; } else { inc = sum[j-1] - sum[j-p]; sinc = tms[j-1] - tms[j-p]; //if(inc<0) cout<<j-1<<" sec "<<j-p<<endl; //cout<<j<<" "<<inc<<" "<<sinc<<endl; } //cout<<j<<" "<<del<<" "<<inc<<" "<<sinc<<endl; temp += del*x+(sinc*j-inc)*y; //cout<<temp<<endl; } //LL temp = del*x + (sinc*p-inc)*y; //cout<<"ans"<<temp<<endl; ans = min(temp,ans); } cout<<ans<<endl; return 0; }
相关文章推荐
- 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 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 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. 1): B. Arpa and a list of numbers
- Codeforces 850B - 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
- 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 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
- Codeforces Round #432 (Div. 2) D - Arpa and a list of numbers