題意:給定兩個 \(n\) 元環,環上每個點有權值,分別為 \(x_i, y_i\)。定義兩個環的差值為
\[\sum_^
\]可以旋轉其中的乙個環,或者將其中乙個環的每種權值加上乙個數。求最小化的差值。
solution: 加數只需要加在乙個上面即可(假設可以為負),那麼差值可以寫成
\[\sum_^+c)^2}
\]我們可以將差值定義為旋轉位數\(k\)與加數\(c\)的函式,即 \(f(k,c)\) 。我們現在要找的就是二元函式的峰值。展開得
\[f(k,c)=\sum + \sum + nc^2 + 2c \sum - 2c\sum - 2 \sum}
\]我們驚喜地發現沒有交叉項,即
\[f(k,c) = g(k) + h(c)
\]那麼我們只需要分別最小化兩部分即可。
考慮\(g(k)\),翻轉序列\(x\),這是乙個迴圈卷積的形式。我們可以將序列\(y\)擴增一倍來轉化為線性卷積。那麼此時
\[g(k) = \sum_^ y_}
\]對應到多項式乘法上,找\(g(k)\)的最小值,即在冪次為 \([n-1,2n-1)\) 的項中找最大係數即可。
考慮\(h(c)\),由於\(m \leq 100\),暴力列舉即可。
#include#define pi acos(-1)
using namespace std;
struct poly
void write()
poly mul(poly pa,poly pb)
poly operator * (const poly &pb)
poly operator *= (const poly &pb)
};int n,m,a[100005],b[100005];
int main()
ans += px + py;
poly x,y;
x.c.resize(n);
for(int i=0;iy.c.resize(2*n);
for(int i=0;ipoly z=x*y;
long long mx=0;
for(int i=0;icout<}
多項式乘法
時間限制 c c 1秒,其他語言2秒 空間限制 c c 262144k,其他語言524288k 64bit io format lld et reo 吃完了元宵,又開始思考數學問題了。這次他拿了兩個多項式 p mathscrp 和 q mathscrq 他知道這兩個多項式的乘積也是乙個多項式,但他不...
多項式乘法
l1和l2是兩個帶頭結點的單鏈表表示的多項式,編寫演算法計算兩個多項式的乘積,運算結果仍用單鏈表進行儲存 include using namespace std typedef struct lnode lnode,linkedlist 查詢計算結果應該插入的位置 param l 鍊錶的頭結點指標 ...
多項式加法 乘法
學校acm上面的題目,題目不難,不少細節。本質就是鍊錶操作,首先是題目要求 輸入 兩組資料,每一組代表乙個一元整係數多項式,有多行組成,其中每一行給出多項式每一項的係數和指數,這些行按指數遞減次序排序,每一組結束行為 0 1 輸出 三組資料,前兩組為一元整係數多項式,最後一組為兩個多項式的和。一元整...