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

    我的室友最近喜欢上了一个可爱的小女生。马上就要到她的生日了,他决定买一对情侣手环,一个留给自己,一个送给她。每个手环上各有 (n) 个装饰物,并且每个装饰物都有一定的亮度。

    但是在她生日的前一天,我的室友突然发现他好像拿错了一个手环,而且已经没时间去更换它了!他只能使用一种特殊的方法,将其中一个手环中所有装饰物的亮度增加一个相同的自然数 (c)(即非负整数)。并且由于这个手环是一个圆,可以以任意的角度旋转它,但是由于上面装饰物的方向是固定的,所以手环不能翻转。需要在经过亮度改造和旋转之后,使得两个手环的差异值最小。

    在将两个手环旋转且装饰物对齐了之后,从对齐的某个位置开始逆时针方向对装饰物编号(1,2,…,n),其中 (n) 为每个手环的装饰物个数, 第 (1) 个手环的 (i) 号位置装饰物亮度为 (xi),第 (2) 个手环的 (i) 号位置装饰物亮度为 (yi),两个手环之间的差异值为(参见输入输出样例和样例解释):

    $$sum_{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)


    很有意思的一个题目,关键是要想到怎么把题目变成推式子,如果分析失误就会像我一样当成(DP)+二分使劲写写不出来。

    处理之前,我们要先把原式中的两个变量固定一个——即假设只有(B)会旋转,并把(B)的亮度整体增加整数(C)(使(C)可正可负即可。这样式子就变成了

    $$sum(x_i + y_i + k) ^ 2$$

    (先暂时忽略(x_i)(y_i)的顺序问题。)

    紧接着我们把式子展开,得到:

    $$sum x_i^2 + sum y_i^2 + N * K ^ 2 + 2 * K * (sum x_i -y_i) - 2 * sum x_i * y_i$$

    前两项是常数项,中间两项用二次函数代入对称轴求最小值,最后一项我们把(y)数列翻转倍长(翻转是便于卷积,倍长是为了可以忽略顺序问题,断环为链。)

    这样如果(y_i)要逆时针转(k)位,那么最后一项就会变成(2 * sum x_i * y_{i + k})。也就是说,倍长处理后,我们只需在(N + 1) -> (N * 2)位找一个最大的值,就是手链顺序对答案产生的最大贡献了。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define LL long long
    const int N = 100010;
    const double pi = acos (-1);
    
    struct Complex {
    	double x, y;
    	Complex (double xx = 0, double yy = 0) {x = xx, y = yy;}
    	Complex operator + (Complex rhs) {return Complex (x + rhs.x, y + rhs.y);}
    	Complex operator - (Complex rhs) {return Complex (x - rhs.x, y - rhs.y);}
    	Complex operator * (Complex rhs) {return Complex (x * rhs.x - y * rhs.y, x * rhs.y + y * rhs.x);}
    }X[N], Y[N], S[N];
    
    int n, m, l, lim = 1, x[N], y[N], r[N]; LL ans, res;
    
    void fast_fast_tle (Complex *A, int type) {
    	for (int i = 0; i < lim; ++i) {
    		if (i < r[i]) {
    			swap (A[i], A[r[i]]);
    		}
    	}
    	for (int mid = 1; mid < lim; mid <<= 1) {
    		Complex Wn (cos (pi / mid), type * sin (pi / mid));
    		for (int p = 0; p < lim; p += (mid << 1)) {
    			Complex w (1, 0);
    			for (int k = 0; k < mid; ++k, w = w * Wn) {
    				Complex xx = A[p + k];
    				Complex yy = w * A[p + k + mid];
    				A[p + k] = xx + yy;
    				A[p + k + mid] = xx - yy;
    			}
    		}
    	}
    	if (type == -1) {
    		for (int i = 0; i < lim; ++i) {
    			A[i].x /= lim;
    		}
    	}
    }
    
    int main () {
    	cin >> n >> m;
    	for (int i = 1; i <= n; ++i) cin >> x[i];
    	for (int i = 1; i <= n; ++i) cin >> y[i];
    	for (int i = 1; i <= n; ++i) {
    		ans += x[i] * x[i];
    		ans += y[i] * y[i];
    	    res += y[i] - x[i];
    	}
    	int T1 = ceil  ((double) res / (double) n);
    	int T2 = floor ((double) res / (double) n);
    	ans += min (
    				n * T1 * T1 - 2 * T1 * res,
    				n * T2 * T2 - 2 * T2 * res
    				);
    	n = n - 1;
    	for (int i = 0; i <= n; ++i) {
    		X[i].x = x[i + 1];
    		Y[i].x = y[n - i + 1];
    	}
    	for (int i = n + 1; i <= n * 2 + 1; ++i) {
    		Y[i] = Y[i - n - 1];
    	}
    	while (lim <= n * 2 + 1) ++l, lim <<= 1;
    	for (int i = 0; i < lim; ++i) {
    		r[i] = (r[i >> 1] >> 1) | ((i & 1) * (lim >> 1));
    	}
    	fast_fast_tle (X, 1);
    	fast_fast_tle (Y, 1);
    	for (int i = 0; i < lim; ++i) {
    		S[i] = X[i] * Y[i];
    	}
    	fast_fast_tle (S, -1);
    	LL tmp = (LL) -1e18;
    	for (int i = n + 1; i <= n * 2 + 1; ++i) {
    		tmp = max (tmp, (LL) (S[i].x + 0.5));
    	}
    	cout << ans - tmp * 2 << endl;
    }
    
    
  • 相关阅读:
    让你忘记 Flash 的15款精彩 HTML5 游戏
    经典网页设计:10个响应式设计的国外购物网站
    个人网站设计:25个国外优秀案例带给你灵感
    震撼!20幅令人难以置信的摄影图片欣赏
    Vex – 超轻量!可以轻松自定义的现代风格弹窗插件
    高端大气上档次!10个精美的国外HTML5网站欣赏
    桂系军阀老大为何不是打仗独步天下的白崇禧?三个方面不如李宗仁(气量,人缘,大局观)
    LEO原创-FMX之你不知道的ARC
    ubuntu64位系统编译时头文件找不到的问题(可以查看g++ -v路径,设置export C_INCLUDE_PATH,CPLUS_INCLUDE_PATH)
    qt设计器中使用自定义控件
  • 原文地址:https://www.cnblogs.com/maomao9173/p/10429000.html
Copyright © 2011-2022 走看看