zoukankan      html  css  js  c++  java
  • ZJOI2014 力 推式子 FFT板题 VJ1000题祭

    ZJOI2014 力 推式子 FFT板题 VJ1000题祭

    题意

    定义

    [F_j = sum_{i = 1}^{j - 1} frac{q_i imes q_j} {(i - j)^2} - sum_{i = j+ 1}^n frac{q_i imes q_j}{(i - j)^2}\ E_i = F_i / q_i ]

    对于(1 leq i leq n),求出(E_i)

    [1 leq n leq 10^5\ 0 < q_i < 10^9 ]

    分析

    直接推式子,我们希望推成卷积的形式

    [E_j = frac{F_j}{q_j}\ = sum_{i = 1}^{j} frac{q_i}{(i - j)^2} - sum_{i=j}^n frac{q_i}{(i - j)^2}\ f_i = q_i,g_i = frac{1}{i^2}\ = sum_{i=1}^j f_i g_{j-i} - sum_{i=j}^n f_i g_{i-j}\ 约定f_0 = g_0 = 0\ = sum_{i = 0}^i f_i g_{j - i} - sum_{i=0}^t f'_{t-i}g_i ]

    于是对左右卷积即可

    代码

    #include<bits/stdc++.h>
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second 
    using namespace std;
    typedef long long ll;
    
    const double PI = acos(-1.0);
    const int maxn = 4e5 + 5;
    
    ll rd(){
    	ll x = 0;
    	int f = 1;
    	char ch = getchar();
    	while(ch < '0' || ch > '9') {
    		if(ch == '-') f = -1;
    		ch = getchar();
    	} 
    	while(ch >= '0' && ch <= '9') {
    		x = x * 10 + ch - '0';
    		ch = getchar();
    	}
    	return x * f;
    }
    
    int n,m;
    
    struct CP{
    	CP(double xx = 0,double yy = 0) {x = xx,y = yy;}
    	double x,y;
    	CP operator + (CP const& B) {return CP(x + B.x,y + B.y);}
    	CP operator - (CP const& B) {return CP(x - B.x,y - B.y);}
    	CP operator * (CP const& B) {return CP(x * B.x - y * B.y,x * B.y + y * B.x);}
    }f[maxn << 1],p[maxn << 1],c[maxn << 1];
    
    int tr[maxn << 1];
    
    void fft(CP *f,bool flag){
    	for(int i = 0;i < n;i++)
    		if(i < tr[i]) swap(f[i],f[tr[i]]);
    	for(int p = 2;p <= n;p <<= 1) {
    		int len = p >> 1;
    		CP tG(cos(2 * PI / p),sin(2 * PI / p));
    		if(!flag) tG.y *= -1;
    		for(int k = 0;k < n;k += p) {
    			CP buf(1,0);
    			for(int l = k;l < k + len;l++){
    				CP tt = buf * f[len + l];
    				f[len + l] = f[l] - tt;
    				f[l] = f[l] + tt;
    				buf = buf * tG;
    			}
    		}
    	}
    }
    
    int main(){
    	n = rd();
    	int nn = n;
    	m = n;
    	for(int i = 1;i <= n;i++)
    		scanf("%lf",&f[i].x),c[n - i].x = f[i].x,p[i].x = (double)(1.0 / i / i); 
    	for(m += n,n = 1;n <= m;n <<= 1);
    	for(int i = 0;i < n;i++)
    		tr[i] = (tr[i >> 1] >> 1) | ((i & 1) ? n >> 1 : 0);
    	fft(f,1);
    	fft(p,1);
    	fft(c,1);
    	for(int i = 0;i < n;i++)
    		f[i] = f[i] * p[i],c[i] = c[i] * p[i];
    	fft(f,0);
    	fft(c,0);
    	for(int i = 1;i <= nn;i++){
    		double res = (f[i].x - c[nn - i].x ) *1.0 / n;
    		printf("%.3f
    ",res);
    	}
    }
    
  • 相关阅读:
    信息收集之Nmap
    namp ssl秘钥安全性检测
    msf测试tomcat
    MobaXterm root用户连接虚拟机时出现Access denied
    最长公共子序列C
    web 入门58-70
    oninput,onpropertychange,onchange的用法和区别
    JavaScript判断图片是否加载完成的三种方式---转
    node.js
    SPP-Net
  • 原文地址:https://www.cnblogs.com/hznumqf/p/14640534.html
Copyright © 2011-2022 走看看