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

题意:一个数列,2个操作,1:删除某个数 代价为x,   2:使得其中一个数+1,代价为 y,问怎样使得这个数列为好数列,好数列定义为这个数列gcd不为1

思路:枚举gcd,比如当gcd == x 时 ,我们对于  k*x  到 (k+1)*x这个区间内 ,要么让里面的数字靠近 (k+1)*x,要么删去, 而且我们假设我们对于某个数字改变p次的时候 代价比删除他要小 ,即 pos *y <=x;

    我们就可以得到在(k+1)*x - pos 到(k+1)*x里面的数字应该选择2操作,前面的选择1操作,前缀和预处理  ,当然我们不用枚举2到1e6,只需要枚举 素数即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 
 5 const int M=2e6+100;
 6 
 7 ll b[M],c[M];
 8 int n;
 9 ll x,y;
10 
11 int main(){
12     scanf("%d%lld%lld",&n,&x,&y);
13     int z;
14     for(int i=1;i<=n;i++){
15         scanf("%d",&z);
16         b[z]++;
17         c[z]+=z;
18     }
19     for(int i=1;i<M;i++){
20         b[i]+=b[i-1];
21         c[i]+=c[i-1];
22     }
23     int pos=x/y;
24     ll ans=n*x;
25     for(int i=2;i<=1000000;i++){
26         ll t=0;
27         for(int j=i;j<=1000000+i&&t<ans;j+=i){
28             int k=max(j-i,j-pos-1);
29             ll xx=(b[j]-b[k])*(ll)j-(c[j]-c[k]);
30             t+=xx*y;
31             t+=(b[k]-b[j-i])*x;
32         }
33         ans=min(ans,t);
34     }
35     cout<<ans<<endl;
36 }

枚举素数的,

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=1e6+100;
 5 const int M=2e6+100;
 6 
 7 ll b[M],c[M];
 8 int n;
 9 ll x,y;
10 int a[N];
11 int l,vis[N];
12 
13 void init(){
14     for(int i=2;i<=N;i++){
15         if(vis[i]==0) a[++l] =i;
16         else continue;
17         for(int j=i;j<=N;j+=i)
18             vis[j]=1;
19     }
20 }
21 int main(){
22     init();
23     scanf("%d%lld%lld",&n,&x,&y);
24     int z;
25     for(int i=1;i<=n;i++){
26         scanf("%d",&z);
27         b[z]++;
28         c[z]+=z;
29     }
30     for(int i=1;i<M;i++){
31         b[i]+=b[i-1];
32         c[i]+=c[i-1];
33     }
34     int pos=x/y;
35     ll ans=n*x;
36     int r=1;
37     for(int kk=1;kk<=l;kk++){
38         ll t=0;
39         int i=a[kk];
40         for(int j=i;j<=1000000+i&&t<ans;j+=i){
41             int k=max(j-i,j-pos-1);
42             ll xx=(b[j]-b[k])*(ll)j-(c[j]-c[k]);
43             t+=xx*y;
44             t+=(b[k]-b[j-i])*x;
45         }
46         ans=min(ans,t);
47     }
48     cout<<ans<<endl;
49 }

 

posted on 2017-09-05 16:52  hhhhx  阅读(112)  评论(0编辑  收藏  举报

导航