zoukankan      html  css  js  c++  java
  • P3723 [AH2017/HNOI2017]礼物

    题目链接:[AH2017/HNOI2017]礼物

    题意:

    两个环x, y 长度都为n

    k可取 0 ~ n - 1      c可取任意值

    求 ∑ ( x[i] - y[(i + k) % n + 1] + c) ^ 2 的最小值

    ans[k] = ∑ ( x[i], y[(i + k) % n + 1] ) ^ 2

    拆项

    发现ans[k] = ∑ x[i] ^ 2 + ∑ y[i] ^ 2  + n * c ^ 2 + 2 * ∑ x[i] * c - 2 * ∑ y[i] * c - 2 * ∑ x[i] * y[(i + k) % n + 1]

    然后 就没有然后了

    暴力一项一项解 处理出所有的ans 找最小值就行了

     ∑ x[i] ^ 2 + ∑ y[i] ^ 2 

    固定的直接算就行

    n * c ^ 2 + 2 * ∑ x[i] * c- 2 * ∑ y[i] * c

    把这个式子看作是关于c的

    动用初中数学二次函数知识算出最小值

    - 2 * ∑ x[i] * y[(i + k) % n + 1]

    那么这个呢? FFT大法好

    这就很板子

    然后是代码

     1 // luogu-judger-enable-o2
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cmath> 
     5 #include <complex>
     6 using namespace std;
     7 const int N = 3e5 + 5;
     8 const double pi = acos(-1);
     9 typedef complex<double> cd;
    10 cd a[N], b[N];
    11 double f[N];
    12 int n, m, lim, l, r[N];
    13 int x[N], y[N], sx, sy;
    14 long long ans;
    15 
    16 inline void init(){
    17     scanf("%d%d", &n, &m);
    18     for(int i = 0; i < n; i++){
    19         scanf("%d", &x[i]);
    20         a[i] = x[i], ans += x[i] * x[i], sx += x[i];
    21     }
    22     for(int i = 0; i < n; i++){
    23         scanf("%d", &y[i]);
    24         b[i] = y[i], ans += y[i] * y[i], sy += y[i]; 
    25     }
    26     
    27     reverse(a, a + n); //翻转a
    28     for(int i = 0; i < n; i++) b[i + n] = b[i];
    29     for(lim = 1; lim < 3 * n; lim <<= 1) l++;//注意是3 * n哦
    30 }
    31 
    32 inline void cal(){
    33     for(int i = 0; i < lim; i++)
    34         r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
    35 }
    36 
    37 void fft(cd * c, int type){
    38     for(int i = 0; i < lim; i++)
    39     if(i < r[i]) swap(c[i], c[r[i]]);
    40     for(int i = 1; i < lim; i <<= 1){
    41         cd xx(cos(pi / i), type * sin(pi / i));
    42         for(int j = 0; j < lim; j += (i << 1)){
    43             cd yy(1, 0);
    44             for(int k = 0; k < i; k++, yy *= xx){
    45                 cd p = c[j + k], q = yy * c[i + j + k];
    46                 c[j + k] = p + q;
    47                 c[i + j + k] = p - q;
    48             }
    49         }
    50     }
    51 }
    52 
    53 int main(){
    54     init();
    55     cal();
    56     int as1 = floor(1.0 * (sy - sx) / n), as2 = ceil(1.0 * (sy - sx) / n);
    57     ans += min(n * as1 * as1 + 2 * (sx - sy) * as1, n * as2 * as2 + 2 * (sx - sy) * as2);
    58     fft(a, 1); fft(b, 1);
    59     for(int i = 0; i < lim; i++) a[i] *= b[i];
    60     fft(a, -1);
    61     for(int i = n - 1; i < (n << 1) - 1; i++)//统计答案 f[n - 1 + i] = ans[i];
    62         f[i] = round(a[i].real() / lim);
    63     ans -= *max_element(f + n - 1, f + (n << 1) - 1) * 2;
    64     printf("%lld", ans);
    65     return 0;    
    66 } 
    View Code
  • 相关阅读:
    jQuery UI DatePicker用法和中文设置
    jQuery的ajax方法
    jQuery遍历复杂的JSON数据
    JavaScript面向对象的写法
    jpa
    日志
    全局异常的处理!
    oracle表空间
    plsql的连接配置
    pLsql使用
  • 原文地址:https://www.cnblogs.com/hjmmm/p/9416090.html
Copyright © 2011-2022 走看看