CF624D - Array GCD
来源:互联网 发布:flash mac中文版 编辑:程序博客网 时间:2024/06/06 05:37
文章大意:
给定一个数列,现在有两种合法操作:
1)选择一段连续区间,把这段区间的数移除,代价为a*区间元素个数,不可移动整个数列。
2)选择某些元素,把这些元素分别加一或减一,元素之间无影响,可以不连续。代价为b*操作元素个数。
现在要求这两种操作,每种操作最多做一次,可以不做,使得剩下的数列中,所有数的最大公约数大于1。求所需的最小代价。
通过YY可以发现,既然不让移除全部区间,就是说,a1或者an至少要有一个留在原来数列,那么可以求a1,a1+1,a1-1,an,an+1,an-1,这六个数的质因数,最后的答案的约数肯定在这六个数的质因数当中。那么久简单了,先分解这六个数,求出它们的质因数(ps:注意本身是大素数的情况),然后枚举质因数,对于每个质因数,求出其最小代价,最后求最小值。
求最小值可以DP也可以尺扫,我用的是尺扫的方法,枚举移除的左右端点L和R,如果当前区间的修改代价之和大于区间移除代价,那么就移除,R++,否则,不移除,L=R+1,R=L。这个复杂度是O(n)的,有兴趣的同学可以自己证明一下这个的复杂度。注意不可以整个区间都移除,需要特判。
<代码很丑,勿喷>
#include<cstdio>#include<iostream>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<map>using namespace std;int shu[1100000];int sushu[110000];long long dai[1100000];long long ans;int n;long long a[1100000];long long aa,bb;int aaa,bbb;map<long long,int> w1,wn;int main(){for(int i=2;i<=1000000;i++){if(!shu[i]){for(int j=i*2;j<=1000000;j+=i)shu[j]=1;}}for(int i=2;i<=1000000;i++){if(!shu[i]){sushu[0]++;sushu[sushu[0]]=i;}}scanf("%d%d%d",&n,&aaa,&bbb);aa=aaa;bb=bbb;for(int i=1;i<=n;i++){int x;scanf("%d",&x);a[i]=x;}for(int i=1;i<=sushu[0];i++){if(a[1]%sushu[i]==0)w1[sushu[i]]=1;if((a[1]-1)%sushu[i]==0)w1[sushu[i]]=1;if((a[1]+1)%sushu[i]==0)w1[sushu[i]]=1;w1[a[1]]=1;w1[a[1]+1]=1;w1[a[1]-1]=1;//if(w1[sushu[i]])printf("sajfdoiajfo 1 %d\n",sushu[i]);if(a[n]%sushu[i]==0)wn[sushu[i]]=1;if((a[n]-1)%sushu[i]==0)wn[sushu[i]]=1;if((a[n]+1)%sushu[i]==0)wn[sushu[i]]=1;wn[a[n]]=1;wn[a[n]-1]=1;wn[a[n]+1]=1;//if(wn[sushu[i]])printf("sajfdoiajfo n %d\n",sushu[i]);}sushu[0]++;sushu[sushu[0]]=a[1];sushu[0]++;sushu[sushu[0]]=a[1]+1;sushu[0]++;sushu[sushu[0]]=a[n];sushu[0]++;sushu[sushu[0]]=a[n]+1;sushu[0]++;sushu[sushu[0]]=a[1]-1;sushu[0]++;sushu[sushu[0]]=a[n]-1;ans=-1;for(int i=1;i<=sushu[0];i++){if(sushu[i]==1)continue;//if(i==10)while(1);//printf("ii=%d sushu=%d\n",i,sushu[i]);if((!w1[sushu[i]])&&(!wn[sushu[i]])){}else{long long q=sushu[i];for(int j=1;j<=n;j++){if(a[j]%q==0){dai[j]=0;}else{if(((a[j]+1)%q==0)||((a[j]-1)%q==0)){dai[j]=bb;}else{dai[j]=aa*(long long)100;}}}int ji=0;long long temp=0;long long anss;for(int j=2;j<=n;j++)dai[j]+=dai[j-1];//for(int j=1;j<=n;j++){//printf("dai[%d]=",j);//cout<<dai[j]<<endl;//}anss=dai[n];for(int j=1;j<=n;j++){temp+=dai[j]-dai[j-1];ji++;if(temp>=(long long)ji*aa){anss=min(anss,dai[j-ji]+dai[n]-dai[j]+(long long)ji*aa);}else{temp=0;ji=0;}}if(ans==-1)ans=anss;ans=min(ans,anss);//printf("ans[%d]=",i);//cout<<ans<<endl;}}cout<<ans<<endl;return 0;}
0 0
- CF624D - Array GCD
- Array GCD
- hdu4947 GCD Array
- bzoj3853 GCD Array
- bzoj 3853 GCD Array
- BZOJ 3853 GCD Array
- Codeforces 623 B. Array GCD
- CodeForces 624D Array GCD
- Codeforces 623B:Array GCD
- CodeForces 623B Array GCD
- codeforces 624d 623b Array GCD
- Educational Codeforces Round 4 D. Array GCD
- Codeforces 624D Array Gcd(数论+dp)
- [DP] Codeforces #623B. Array GCD
- hdu 4947 GCD Array 莫比乌斯反演
- 【树状数组 + 容斥原理】 HDOJ 4947 GCD Array
- HDU 4947 GCD Array 反演+树状数组维护
- AIM Tech Round (Div. 2) D. Array GCD(dp)
- CF624C - Graph and String
- 为GoLang增加aes的ECB模式支持
- UE4使用Visual Studio编译配置详解
- 1020. 月饼 (25)
- 【JAVA】4、classpath属性的作用及使用方法
- CF624D - Array GCD
- 集训队专题(4)1001 King Arthur's Birthday Celebration
- 51Nod 1083 矩阵取数问题(简单DP)
- JacksonWant ——iOS系统学习笔记(一)
- 引子
- 【Android开发小记--18】数据存储2--SharedPreferences 以及 PreferenceActivity
- 代码清单4-2
- path classpath
- CF100015A - Another Rock-Paper-Scissors Problem