您的位置:首页 > 其它

【ZJOI2017 Round2练习&BZOJ4827】D1T3 gift(FFT)

2017-04-19 20:46 399 查看

题意:

 

思路:可以看出题目所要最小化的是这样一个形式:

拆出每一项之后发现会变化的项只有sigma a[i]*b[i+t]与c^2,c*(a[i]-b[i])

c可以在外层枚举,剩下的只有sigma a[i]*b[i+t] (i=0..n-1)

因为FFT只能解决simga a[i]*b[n-i]

所以我们可以把a翻转,这样就化成了如上的形式

c[n+t+1]=a[n-i+1]*b[i+t] (i=0..n-1)

取出最小(大)的c[i],与外层枚举的c共同求出答案,取最小值

FFT模板,值得一背

1 type cp=record
2          x,y:extended;
3         end;
4      arr=array[0..510000]of cp;
5 var c,d,cur:arr;
6     a,b:array[0..510000]of longint;
7     n,i,m:longint;
8     ans,sum,s1,s2:int64;
9
10 procedure swap(var x,y:cp);
11 var t:cp;
12 begin
13  t:=x; x:=y; y:=t;
14 end;
15
16 function jia(a,b:cp;f:longint):cp;
17 begin
18  if f=-1 then
19  begin
20   b.x:=-b.x; b.y:=-b.y;
21  end;
22  jia.x:=a.x+b.x;
23  jia.y:=a.y+b.y;
24 end;
25
26 function mult(a,b:cp):cp;
27 begin
28  mult.x:=a.x*b.x-a.y*b.y;
29  mult.y:=a.x*b.y+a.y*b.x;
30 end;
31
32 function min(x,y:int64):int64;
33 begin
34  if x<y then exit(x);
35  exit(y);
36 end;
37
38 function max(x,y:int64):int64;
39 begin
40  if x>y then exit(x);
41  exit(y);
42 end;
43
44 procedure fft(var a:arr;n,f:longint);
45 var i,j,k,m:longint;
46     w,u,v:cp;
47 begin
48  i:=n>>1; j:=1;
49  while j<n do
50  begin
51   if i<j then swap(a[i],a[j]);
52   k:=n>>1;
53   while k and i>0 do
54   begin
55    i:=i xor k;
56    k:=k>>1;
57   end;
58   i:=i xor k;
59   inc(j);
60  end;
61  m:=2;
62  while m<=n do
63  begin
64   w.x:=cos(2*pi*f/m); w.y:=sin(2*pi*f/m);
65   cur[0].x:=1; cur[0].y:=0;
66   for i:=1 to m-1 do cur[i]:=mult(cur[i-1],w);
67   i:=0;
68   while i<n do
69   begin
70    j:=i;
71    while j<i+(m>>1) do
72    begin
73     u:=a[j]; v:=mult(a[j+(m>>1)],cur[j-i]);
74     a[j]:=jia(u,v,1);
75     a[j+(m>>1)]:=jia(u,v,-1);
76     inc(j);
77    end;
78    i:=i+m;
79   end;
80   m:=m<<1;
81  end;
82 end;
83
84 procedure solve;
85 var i,j,len:longint;
86 begin
87  for i:=0 to n-1 do c[i].x:=a[i];
88  for i:=0 to n-1 do d[i].x:=b[i];
89  i:=0; j:=n-1;
90  while i<=j do
91  begin
92   swap(d[i],d[j]);
93   inc(i); dec(j);
94  end;
95  len:=1;
96  while len<=n+n do len:=len<<1;
97  for i:=n to len-1 do
98  begin
99   c[i].x:=0; d[i].x:=0;
100  end;
101  for i:=0 to len-1 do
102  begin
103   c[i].y:=0; d[i].y:=0;
104  end;
105  fft(c,len,1);
106  fft(d,len,1);
107  for i:=0 to len-1 do c[i]:=mult(c[i],d[i]);
108  fft(c,len,-1);
109  for i:=0 to len-1 do c[i].x:=trunc(c[i].x/len+0.5);
110  for i:=n to len-1 do c[i mod n].x:=c[i mod n].x+c[i].x;
111  sum:=-(1<<62);
112  for i:=0 to n-1 do sum:=max(sum,round(c[i].x));
113  sum:=-sum*2;
114 end;
115
116 begin
117  assign(input,'bzoj4827.in'); reset(input);
118  assign(output,'bzoj4827.out'); rewrite(output);
119  readln(n,m);
120  for i:=0 to n-1 do read(a[i]);
121  for i:=0 to n-1 do read(b[i]);
122  ans:=1<<62;
123  solve;
124  for i:=0 to n-1 do
125  begin
126   s1:=s1+a[i]-b[i];
127   s2:=s2+a[i]*a[i]+b[i]*b[i];
128  end;
129  for i:=-m to m do ans:=min(ans,int64(n)*i*i+2*s1*i+s2+sum);
130  writeln(ans);
131  close(input);
132  close(output);
133 end.

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: