noip類比【array】

來源:互聯網
上載者:User

標籤:\n   opened   font   array   splay   names   如何   sed   gcd   

array

      by ysy

【題目描述】

    給定一個長度為n的數列,每次你可以進行以下操作之一:

(1)將一個數+a;

(2)將一個數-a;

(3)將一個數+b;

(4)將一個數-b;

你需要將所有數全部變為0,求最小運算元。

【輸入資料】

       第一行三個整數n,a,b,第二行n個整數x1~xn表示數列。

【輸出資料】

一行一個整數表示答案。無解輸出-1。

【範例輸入】

2 2 3

1 2

【範例輸出】

 3

【資料範圍】

對於10%的資料,n,a,b,|xi|<=1000。

對於30%的資料,n,a,b<=1000。

對於另外10%的資料,a=1。

對於另外10%的資料,a=2,b=3。

對於100%的資料,1<=n<=105,1<=a,b<=109,|xi|<=109。

【題解思路】

很容易轉化成數學模型:ax+by = c,使(|x|+|y|)min。

對於方程ax+by = c,我們可以用exgcd求出一組解。

當a,b互質時,保證ax+by = c有解。

設d = gcd(a,b).a/d*x+b/d*y = c/d;

此時可求出一組特解:x‘,y‘。

則ax+by = c的通解可以表示為:x = c/d * x‘ + k * b/d,y = c/d * y‘ - k * a/d;

然後如何使(|x|+|y|)min。考慮到對於上述通解,我們可以打表或意念理解,這是個單峰函數。

即存在唯一且確定值k,使得|c/d*x‘ + k*b/d|+|c/d*y‘ - k* a/d|最小,儘可能使絕對值接近零,那麼對於這兩個數使得x取得最小的正數或最大的負數(絕對值盡量接近0)。

時間複雜度 O(nlog|xi|)

#include<bits/stdc++.h>using namespace std;#define ll long long#define ull unsigned long long#define rep(k,i,j) for(int k = i;k <= j; ++k) #define FOR(k,i,j) for(int k = i;k >= j; --k)inline int read(){    int x=0,f=1; char ch=getchar();    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}    while(ch>=‘0‘&&ch<=‘9‘){x=(x<<1)+(x<<3)+ch-‘0‘;ch=getchar();}    return x*f;}int n,a,b,k;inline void exgcd(int a,int b,int m,ll &x,ll &y){    if(!b) x = m/a,y = 0;    else {        exgcd(b,a%b,m,x,y);        swap(x,y);        y -= a/b*x;    }}inline int gcd(int a,int b){return b ? gcd(b,a%b) : a;}ll x,y,p;int main(){    freopen("array.in","r",stdin);    freopen("array.out","w",stdout);    n = read(),a = read(),b = read();    k = gcd(a,b);    a /= k,b /= k;    if(a<b) swap(a,b);    rep(i,1,n){        int j = read();        if(j%k) printf("-1\n"),exit(0);        exgcd(a,b,j/k,x,y);        if(y<0) {            x -= b*((-y)/a+1);            y += a*((-y)/a+1);        }        x += b*(y/a);        y -= a*(y/a);        p += min(abs(x)+abs(y),abs(x+b)+abs(y-a));    }    printf("%lld\n",p);    return 0;} /*2 2 31 2*/
View Code

 

noip類比【array】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.