[HNOI2017]礼物

Posted D O Time

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[HNOI2017]礼物相关的知识,希望对你有一定的参考价值。

因为可以加上一个常数C,说是非负整数,但其实A手环加上,就等于B手环减去,于是把m范围扩充到[-100,100]即可。

然后所求变为:

$$\\sum (x_i-y_i+C)$$

接着拆开,可以得到:

$$\\sum(x_i^2+y_i^2+C^2)+2*C*\\sum(x_i-y_i)+2*\\sum(x_i*y_i)$$

然后发现这些有常量,可变的C所对应的x和y是常数,而与顺序有关的xi*yi又是与C无关的。所以我们可以先求出的最大值xi*yi。如果我们将B手环在输入之后反转一下,可以发现当翻转前A与B发生错位之时,每一个错位都可以对应反转之后的B与A的FFT的乘积的各个项的系数。

 然后再枚举C从[-m,m]那么答案就出来了。

不会FFT的就去学吧。

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<complex>
 4 #include<iostream>
 5 #include<algorithm>
 6 #define C complex<double>
 7 #define pf(a) ((a)*(a))
 8 using namespace std;
 9 const int MAXN=1000000,INF=0x3f3f3f3f;
10 const double pi=acos(-1.0);
11 int n,m,L,G,Max,Val,ans=INF,sum1,sum2;
12 int R[MAXN],V[MAXN];
13 C A[MAXN],B[MAXN];
14 inline int gi(){int res; scanf("%d",&res); return res;}
15 void FFT(C *a,int p)
16 {
17   for(int i=0;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]);
18   for(int i=1;i<n;i<<=1)
19     {
20       C wn(cos(pi/i),sin(p*pi/i)),x,y;
21       for(int j=0;j<n;j+=(i<<1))
22         {
23           C w(1,0);
24           for(int k=0;k<i;k++,w*=wn)
25             {
26               x=a[j+k],y=w*a[j+k+i];
27               a[j+k]=x+y;
28               a[j+k+i]=x-y;
29             }
30         }
31     }
32 }
33 int main()
34 {
35   freopen("gift.in","r",stdin);
36   freopen("gift.out","w",stdout);
37   n=gi();Max=gi(); n--;
38   for(int i=0;i<=n;i++)A[i]=gi();
39   for(int i=0;i<=n;i++)B[i]=gi();
40   for(int i=0;i<=n;i++)
41     {
42       sum1+=pf(A[i].real())+pf(B[i].real());
43       sum2+=A[i].real()-B[i].real();
44     }
45   m=n+n; reverse(B,B+n+1);
46   for(n=1;n<=m;n<<=1)L++;L--;
47   for(int i=0;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<L);
48   FFT(A,1); FFT(B,1);
49   for(int i=0;i<=n;i++)A[i]*=B[i];
50   FFT(A,-1);
51   for(int i=0;i<=m;i++)V[i]=(int)(A[i].real()/n+0.5);
52   n=m/2; Val=V[n];
53   for(int i=0;i<=n-1;i++)
54     if(Val<V[i]+V[n+i+1])
55       Val=V[i]+V[n+i+1];
56   Val*=2;
57   for(int c=-Max;c<=Max;c++)
58     ans=min(ans,sum2*2*c+(n+1)*c*c-Val);
59   printf("%d\\n",ans+sum1);
60   return 0;
61 }

以上是关于[HNOI2017]礼物的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 4827: [HNOI2017]礼物 (FFT)

BZOJ4827: [Hnoi2017]礼物

[BZOJ4827][Hnoi2017]礼物

BZOJ4827: [Hnoi2017]礼物

HNOI2017礼物

BZOJ4827HNOI2017礼物(FFT)