BZOJ3527[ZJOI]力

无题面神题

原题意:

求所有的Ei=Fi/qi。

题解:

qi被除掉了,则原式中的qj可以忽略。

用a[i]表示q[i],用b[j-i]来表示±1/((j-i)^2)(j>i时为正,j<i时为负)

则求E[j]就是多项式乘法了。

因为是FFT,所以b的下标要增加到0及以上

这题时限有30s,比某题友好多了。

代码:

type
  xs=record
    x,y:double;
  end;
  arr=array[0..1000000]of xs;
var
  e,t:arr;
  a:array[1..5]of arr;
  n,m,i:longint;
function jian(a,b:xs):xs;
begin
  jian.x:=a.x-b.x;
  jian.y:=a.y-b.y;
end;
function jia(a,b:xs):xs;
begin
  jia.x:=a.x+b.x;
  jia.y:=a.y+b.y;
end;
function cheng(a,b:xs):xs;
begin
  cheng.x:=a.x*b.x-a.y*b.y;
  cheng.y:=a.x*b.y+a.y*b.x;
end;
procedure fft(xx,s,nn,mm:longint);
var
  i,j:longint;
  w:xs;
begin
  if nn=1 then
  begin a[xx+2,s]:=a[xx,s]; exit; end;
  for i:=0 to nn div 2-1 do
  begin t[i]:=a[xx,i*2+s]; t[i+nn div 2]:=a[xx,i*2+1+s]; end;
  for i:=0 to nn-1 do a[xx,s+i]:=t[i];
  fft(xx,s,nn div 2,mm*2); fft(xx,s+nn div 2,nn div 2,mm*2);
  for i:=0 to nn div 2-1 do
  begin
    j:=s+i;
    w:=cheng(e[i*mm],a[xx+2,j+nn div 2]);
    t[j]:=jia(a[xx+2,j],w);
    t[j+nn div 2]:=jian(a[xx+2,j],w);
  end;
  for i:=s to s+nn-1 do a[xx+2,i]:=t[i];
end;
begin
  read(m);
  for i:=0 to m-1 do read(a[1,i].x);
  for i:=1 to m-1 do a[2,i].x:=-1/(m-i)/(m-i);
  for i:=m+1 to m*2-1 do a[2,i].x:=1/(i-m)/(i-m);
  n:=1;
  while n<m*2 do n:=n*2;
  for i:=0 to n-1 do e[i].x:=cos(pi*2*i/n);
  for i:=0 to n-1 do e[i].y:=sin(pi*2*i/n);
  fft(1,0,n,1); fft(2,0,n,1);
  for i:=0 to n-1 do a[3,i]:=cheng(a[3,i],a[4,i]);
  for i:=0 to n-1 do e[i].y:=-e[i].y;
  fft(3,0,n,1);
  for i:=m to m*2-1 do writeln((a[5,i].x/n):0:3);
end.
时间: 2024-08-10 19:49:30

BZOJ3527[ZJOI]力的相关文章

【BZOJ-3527】力 FFT

3527: [Zjoi2014]力 Time Limit: 30 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 1544  Solved: 899[Submit][Status][Discuss] Description 给出n个数qi,给出Fj的定义如下: 令Ei=Fi/qi,求Ei. Input 第一行一个整数n. 接下来n行每行输入一个数,第i行表示qi. n≤100000,0<qi<1000000000 Output n行,第i行

bzoj3527: [Zjoi2014]力

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 const int maxn=400005; 8 const double PI=acos(-1); 9 struct node{ 10 double real,imag; 11 void

BZOJ3527 [Zjoi2014]力 【fft】

题目 给出n个数qi,给出Fj的定义如下: 令Ei=Fi/qi,求Ei. 输入格式 第一行一个整数n. 接下来n行每行输入一个数,第i行表示qi. 输出格式 n行,第i行输出Ei.与标准答案误差不超过1e-2即可. 输入样例 5 4006373.885184 15375036.435759 1717456.469144 8514941.004912 1410681.345880 输出样例 -16838672.693 3439.793 7509018.566 4595686.886 1090304

bzoj3527: [Zjoi2014]力 卷积+FFT

先写个简要题解:本来去桂林前就想速成一下FFT的,结果一直没有速成成功,然后这几天断断续续看了下,感觉可以写一个简单一点的题了,于是就拿这个题来写,之前式子看着别人的题解都不太推的对,然后早上6点多推了一个多小时终于发现了一个很巧妙的方法,首先问题的关键在于后半个式子,因为显然前半个式子很容易想到卷积的形式,那么直接FFT就好了,但是后半部分不好考虑,一般肯定是通过类似换元的做法得出结论,所以到中间有一步就有点难度,那个地方我一直卡.后来突然想到,既然前半部分i<j时那么好处理,那么i>j的情

关于万恶的多项式

模板: 1 //Achen 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdlib> 6 #include<vector> 7 #include<cstdio> 8 #include<queue> 9 #include<cmath> 10 #include<set> 11 #include&l

[复习]多项式和生成函数相关内容

[复习]多项式和生成函数相关内容 多项式 涉及的方面 主要在于多项式的乘法,也就是\(FFT,NTT,MTT\). 但是也多项式的求逆,\(exp\),\(ln\),开根,求导,积分等操作. 多项式乘法 并没有什么好复习的,记好板子就行了.同样也是多项式运算的基础. 泰勒展开&麦克劳林级数 泰勒展开: 如果\(f(x)\)在\(x0\)处存在\(n\)阶导,那么就有: \[\begin{aligned}f(x)&=f(x0)+\frac{f^1(x0)}{1!}(x-x0)+\frac{f

【bzoj3527】[Zjoi2014]力 FFT

2016-06-01  21:36:44 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3527 我就是一个大傻叉 微笑脸 1 #include<bits/stdc++.h> 2 #define inf 1000000000 3 #define ll long long 4 #define N 500005 5 using namespace std; 6 int read(){ 7 int x=0,f=1;char ch=getchar

BZOJ 3527 ZJOI 2014 力 FFT

题目大意 定义 求E[i] = F[i] / q[i] 思路 经过推导发现最后形成了卷积的形式,之后直接套用FFT就行了. 注意卷积卷起来之后占用的是2倍的空间.. CODE #define _CRT_SECURE_NO_WARNINGS #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MA

【BZOJ3527】【ZJOI2014】力

"FFT不是随手写?"我终于能说这样的话了?w? 原题: 给出n个数qi,给出Fj的定义如下: 令Ei=Fi/qi,求Ei. FFT嘛,直接推公式 然后就变成俩卷积了,FFT即可 代码(还没写