1. 程式人生 > >[AH/HNOI2017]禮物

[AH/HNOI2017]禮物

小女生 namespace ans 裝飾 style -h baseline script 最小值

題目描述

我的室友最近喜歡上了一個可愛的小女生。馬上就要到她的生日了,他決定買一對情侶手環,一個留給自己,一個送給她。每個手環上各有 n 個裝飾物,並且每個裝飾物都有一定的亮度。

但是在她生日的前一天,我的室友突然發現他好像拿錯了一個手環,而且已經沒時間去更換它了!他只能使用一種特殊的方法,將其中一個手環中所有裝飾物的亮度增加一個相同的自然數 c(即非負整數)。並且由於這個手環是一個圓,可以以任意的角度旋轉它,但是由於上面裝飾物的方向是固定的,所以手環不能翻轉。需要在經過亮度改造和旋轉之後,使得兩個手環的差異值最小。

在將兩個手環旋轉且裝飾物對齊了之後,從對齊的某個位置開始逆時針方向對裝飾物編號1,2,…,n,其中 n 為每個手環的裝飾物個數, 第 1 個手環的 i 號位置裝飾物亮度為 xi,第 2 個手環的 i 號位置裝飾物亮度為 yi,兩個手環之間的差異值為(參見輸入輸出樣例和樣例解釋):

\sum_{i=1}^{n} (x_i-y_i)^2?i=1?n??(x?i???y?i??)?2??

麻煩你幫他計算一下,進行調整(亮度改造和旋轉),使得兩個手環之間的差異值最小,這個最小值是多少呢?

輸入輸出格式

輸入格式:

輸入數據的第一行有兩個數n, m,代表每條手環的裝飾物的數量為n,每個裝飾物的初始亮度小於等於m。

接下來兩行,每行各有n個數,分別代表第一條手環和第二條手環上從某個位置開始逆時針方向上各裝飾物的亮度。

輸出格式:

輸出一個數,表示兩個手環能產生的最小差異值。註意在將手環改造之後,裝飾物的亮度

可以大於 m。

輸入輸出樣例

輸入樣例#1:
5 6
1 2 3 4 5
6 3 3 4 5
輸出樣例#1:
1

說明

【樣例解釋】

需要將第一個手環的亮度增加1,第一個手環的亮度變為: 2 3 4 5 6

旋轉一下第二個手環。對於該樣例,是將第二個手環的亮度6 3 3 4 5向左循環移動一個位置,使得第二手環的最終的亮度為: 3 3 4 5 6。

此時兩個手環的亮度差異值為1

【數據範圍】

30%的數據滿足n≤500, m≤10;

70%的數據滿足n≤5000;

100%的數據滿足1≤n≤50000, 1≤m≤100, 1≤ai≤m。

ans=∑(xi+c-y(i+p)%n)2

=∑(xi+c)^2-2xiy(i+p)%n-2*c*y(i+p)%n+y(i+p)%n^2

=∑-2xiy(i+p)%n+∑(xi+c)^2-2*c*y(i+p)%n

+y(i+p)%n^2

∑-2xiy(i+p)%n=∑-2xiyi+p

反轉x得

∑-2xn-i+1yi+p 對於每個p就是,結果就是第n+p+1項

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 using namespace std;
  7 double pi=acos(-1.0);
  8 const int N=50005;
  9 struct Complex
 10 {
 11     double r,i;
 12     Complex(double r=0,double i=0):r(r),i(i) {};
 13     Complex operator+(const Complex &x) 
 14     {
 15         return Complex(r+x.r,i+x.i);
 16     }
 17     Complex operator-(const Complex &x) 
 18     {
 19         return Complex(r-x.r,i-x.i);
 20     }
 21     Complex operator*(const Complex &x) 
 22     {
 23         return Complex(r*x.r-i*x.i,i*x.r+r*x.i);
 24     }
 25 }A[8*N],B[8*N],C[8*N];
 26 int ans1,ans,ans2,ansx,ansy;
 27 int n,m,p[50001],q[100001],len;
 28 void rader(Complex F[],int len)
 29 {int i;
 30     int j=len/2;
 31     for (i=1;i<len-1;i++)
 32     {
 33         if (i<j)swap(F[i],F[j]);
 34          int k=len/2;
 35          while (j>=k)
 36          {
 37             j-=k;
 38             k/=2;
 39          }
 40          if (j<k) j+=k;
 41     }
 42 }
 43 void FFT(Complex F[],int len,int t)
 44 {int i,j,k;
 45     rader(F,len);
 46     for (i=2;i<=len;i=i*2)
 47     {
 48         Complex wn;
 49         wn.r=cos(t*2*pi/i);wn.i=sin(t*2*pi/i);
 50         for (j=0;j<len;j+=i)
 51         {
 52             Complex E;
 53             E.r=1;E.i=0;
 54              for (k=j;k<j+i/2;k++)
 55               {
 56                     Complex u=F[k];
 57                     Complex v=E*F[k+i/2];
 58                 F[k]=u+v;
 59                 F[k+i/2]=u-v;
 60                 E=E*wn;
 61               }
 62         }
 63     }
 64     if (t==-1)
 65      for (i=0;i<len;i++)
 66       F[i].r/=len;
 67 }
 68 int main()
 69 {int i,j;
 70     cin>>n>>m;
 71     for (i=1;i<=n;i++)
 72     {
 73         scanf("%d",&p[i]);
 74     }
 75     for (i=1;i<=n;i++)
 76     {
 77         scanf("%d",&q[i]);
 78         q[n+i]=q[i];
 79     }
 80     for (i=1;i<=n;i++)
 81     ans1=ans1+p[i]*p[i]+q[i]*q[i];
 82      len=1;
 83       while (len<4*n) len*=2;
 84       for (i=1;i<=n;i++)
 85        A[i-1].r=p[n-i+1];
 86       for (i=1;i<=2*n;i++)
 87        B[i-1].r=q[i-1];
 88       FFT(A,len,1);FFT(B,len,1);
 89       for (i=0;i<len;i++)
 90        C[i]=A[i]*B[i];
 91        FFT(C,len,-1); 
 92        
 93       for (i=0;i<=n-1;i++)
 94       {
 95         ans2=max(ans2,(int)(C[i+n+1].r+0.5));
 96         ansx+=p[i+1];
 97         ansy+=q[i+1];
 98       }
 99       ans=2e9;
100       for (i=-m;i<=m;i++)
101       {
102         int ans3=ans1-2*ans2;
103         ans=min(ans,ans3+2*i*ansx-2*i*ansy+n*i*i);    
104         //cout<<i<<‘ ‘<<ans<<endl;
105       }
106     cout<<ans;
107 }

[AH/HNOI2017]禮物