Problem
You are given array ai of length n. You may consecutively apply the operations to this array:
- Remove some subsegment (continuous subsequence) of length m < N and pay for it m• a coins;
- Change some elements of the array is at a 1, and pay b coins for each change.
Please note that each of the operations may is applied at the most once (and May is not applied at all) so can remove only one Segment and each number is changed (increased or decreased) by at the most 1. Also note, that's allowed to delete the whole array.
Your goal is to calculate the minimum number of coins so you need to spend in order to make the greatest common divisor Of the elements of the resulting array be greater than 1.
Input
The first line of the input contains integers n, a and b (1≤ n ≤1 00 0 000, 0≤ a, b ≤109)-the length of the array, the cost of removing a single element in the Firs T operation and the cost of changing an element, respectively.
The second line contains n integers ai (2≤ a I ≤109)-elements of the array.
Output
Print a single number-the minimum cost of changes needed to obtain an array, such that the greatest common divisor of Al L It elements is greater than 1.
Sample Test (s) input
3 1 4
4 2 3
Output
1
Input
5 3 2
5 17 13) 5 6
Output
8
Input
8 3 4
3 7 5 4 3 12 9 4
Output
13
Note
In the first sample, the optimal is to remove number 3 and pay 1 coin for it.
In the second sample you need to remove a segment [+] and then decrease number 6. The cost of these changes was equal to 2·3 + 2 = 8 coins.
Test Instructions
Give you the number of n, you can perform two operations at most once, one is to remove a continuous sequence cannot move the whole sequence, the price is the sequence length *a, the second is to choose some number change 1, that can be added one, some minus one, the price is the number of numbers *b
Finally, the greatest common divisor of all the remaining numbers is greater than 1 for the least cost.
Analysis
Because all the numbers cannot be removed, a[1] and A[n] will have at least one left, so find a[1]+1 in all a[n]-1 of A[1]-1, A[1], a[n, a[n]+1, factorization], greatest common divisor six numbers.
The process of finding a number T greatest common divisor is j from 2 to square root T, if T can divide j,j is a qualitative factor, save it, and then t always divided by J, in addition to not divisible, and finally judge the remaining number if more than 1, that should be it itself, that means he is a prime, also to save up. Be careful not to repeat when you save. This will not time out, if you do a prime table and then a prime number to determine whether it is the factor will be timed out.
After looking for each factorization, carry out a ruler sweep (there is also a method is DP (to be supplemented)), left sweep to the right, pre-processing the number of the first I have several need to change (Bnum[i]), there are several must be removed (Anum[i]).
Sweep, the cost of removing the interval L to R is Acost, the cost of not removing is bcost, when the bcost<=acost is not removed more cost-effective, so L update to r+1, and save the previous number to modify the cost oldbcost, Otherwise the calculation will only remove this interval, and the other intervals can be modified to reach the target, at what cost (Oldbcost + Acost + (Bnum[n]-bnum[r]) * b), and then update the answer. When it comes to the cost. If a number must be removed, the cost of the modification is set to infinity.
Code
#include <stdio.h> #include <algorithm> #define LL long long#define N 1000005using namespace Std;ll n,a,b,m[n] , P[n],bnum[n],anum[n],primefactornum,minc=1e18;void Saveprime (ll a) {int nosaved=1; for (int i=0; i<primefactornum && nosaved; i++) if (a==p[i]) nosaved=0; if (nosaved) p[primefactornum++]=a;} void Findprimefactor (ll a) {for (int i=-1; i<=1; i++) {int j,t=a+i; for (j=2; j*j<=t; J + +) {if (t%j==0) {saveprime (j); while (t%j==0) t/=j; }} if (t>1) saveprime (t); }}ll cost (ll num,ll factor) {if (num%factor==0) return 0; if ((num+1)% factor && (num-1)% factor) return 1e17;//+1 or-1 cannot be divisible by factor return B; void solve (ll factor) {ll l=1,r,bcost=0,acost=0,oldbcost=0; while (m[l],factor) = = 0 && L <= N) l++;//the left side filters out the continuous sequence if (L = = n+1) {minc=0) that does not need to be changed; ReTurn } R = L-1; Bnum[0] = anum[0] = 0; for (int i=1; i<=n; i++) {ll tmp=cost (m[i],factor); if (tmp = = b) bnum[i] = bnum[i-1]+1; else bnum[i] = bnum[i-1]; if (tmp = = 1e17) Anum[i] = anum[i-1]+1; else anum[i] = anum[i-1]; } if (anum[n] = = 0) minc = min (minc, bnum[n] * b); while (r<n) {acost+=a; r++; if (BCOST<1E17) bcost+=cost (m[r],factor); if (bcost<=acost) {l=r+1; Oldbcost+=bcost; bcost=acost=0; } else {if (anum[n]-anum[r]==0) minc = min (minc, oldbcost + acost + (Bnum[n]- BNUM[R]) * b); }}}int Main () {scanf ("%i64d%i64d%i64d", &n,&a,&b); for (int i=1; i<=n; i++) scanf ("%i64d", &m[i]); Findprimefactor (m[1]); Findprimefactor (M[n]); for (int i=0; i<primefactornum && minc; i++) Solve (p[i]); printf ("%i64d", minc); return 0;}
"Codeforces 624D" Array GCD