【[AH2017/HNOI2017]禮物】
阿新 • • 發佈:2019-02-11
include names pan int sig lin i++ std const
一道神題233。。。其實要是把思路想通了也不是很難。
正文部分:
設經過了各種操作之後的數列為\(A\)與\(B\),總增加量為\(x\)。
那麽第\(i\)項所造成的影響就是
\((A_i+x-B_i)^2=A_i^2+x^2+B_i^2+2A_ix-2A_iB_i-2xB_i^2\)
然而\(A\)手環加上相等於\(B\)手環減去,所以\(m\)的範圍變為\(-100\sim100\)
那麽我們可以輕松的得到這兩個數列的總影響:
\(\sum_{i=1}^{i=n}(A_i+x-B_i)^2\)
嘗試把這個式子展開,成為:
\(\sum_{i=1}^{i=n}A_i^2+\sum_{i=1}^{i=n}B_i^2+n*x^2+2x(\sum_{i=1}^{i=n}A_i-\sum_{i=1}^{i=n}B_i)-2\sum_{i=1}^{i=n}A_iB_i\)
這時發現除了最後一項其他項全是固定的,所以我們只需要讓最後一項最大即可,可以用\(fft\)來求解:
My code
#include <bits/stdc++.h> #define il inline #define gc getchar #define FI "gift" const int MAXN = 4e6 + 10; const int INF = 0x7f7f7f7f; const double pi = acos(-1); using namespace std; il int read() { int res = 0;char c;bool sign = 0; for(c = gc();!isdigit(c);c = gc()) sign |= c == ‘-‘; for(;isdigit(c);c = gc()) res = (res << 1) + (res << 3) + (c ^ 48); return sign ? -res : res; } il void FileIO() { freopen(FI".in","r",stdin); freopen(FI".out","w",stdout); return; } struct Cpx { double r,i; Cpx(){} Cpx(double x,double y) { r = x,i = y; } Cpx operator + (const Cpx& x) const { return Cpx(r + x.r,i + x.i); } Cpx operator - (const Cpx& x) const { return Cpx(r - x.r,i - x.i); } Cpx operator * (const Cpx& x) const { return Cpx(r * x.r - i * x.i,r * x.i + i * x.r); } void operator *= (Cpx& x) { *this = *this * x; return; } }a[MAXN],b[MAXN]; int n,m,i,j,k,R[MAXN],_a[MAXN],_b[MAXN]; int sqr_a,sqr_b,sum_a,sum_b,li,x,ans = INF; il void fft(Cpx a[MAXN],int f) { int i,j,k; for(i = 0;i < li;i++) { if(i < R[i]) swap(a[i],a[R[i]]); } for(i = 1;i < li;i <<= 1) { Cpx wn(cos(pi / i),f * sin(pi / i)); for(j = 0;j < li;j += (i << 1)) { Cpx w(1,0); for(k = 0;k < i;k++,w *= wn) { Cpx x = a[j + k],y = w * a[j + k + i]; a[j + k] = x + y;a[j + k + i] = x - y; } } } return; } int main() { // FileIO(); n = read();m = read(); for(i = 1;i <= n;i++) { _a[i] = read(); sqr_a += _a[i] * _a[i]; sum_a += _a[i]; } for(i = 1;i <= n;i++) { _b[i] = read(); sqr_b += _b[i] * _b[i]; sum_b += _b[i]; } for(i = 1;i <= n;i++) { a[i].r = a[i + n].r = _a[i]; b[i].r = _b[n - i + 1]; } int t = 0;li = 1;while(li <= n*3) li <<= 1,t++; for(i = 0;i <= li;i++) { R[i] =(R[i >> 1] >> 1 | ((i & 1) << (t - 1))); } fft(a,1);fft(b,1); for(i = 0;i <= li;i++) a[i] *= b[i]; fft(a,-1); for(i = 0;i <= li;i++) { a[i].r = (int)(a[i].r / li + 0.5); } for(i = 1;i <= n;i++) { for(x = -m;x <= m;x++) { int tmp = sqr_a + sqr_b + n * x * x; tmp += 2 * x *(sum_a - sum_b); ans = min(ans,tmp - 2 * (int)a[i + n].r); } } printf("%lld",1LL * ans); }
【[AH2017/HNOI2017]禮物】