• 「ZJOI2014」力


    题目链接:Click here

    Solution:

    把式子拿下来

    [E_k=sum_{i=1}^{k-1} {q_i over (k-i)^2} -sum_{i=k+1} ^ n {q_i over (i-k)^2} ]

    构造一个生成函数(C(x)=sum_{i=1}^n {1 over i^2} x^i),那么式子就变成了这样

    [E_k=sum_{i=1}^{k-1} q_i C_{k-i} -sum_{i=k+1} ^ n q_i C_{i-k} ]

    我们把(q(x)\,\,reverse)一下,得到新的多项式(p(x)),那么式子就是这个样子的了

    [E_k=sum_{i=1}^{k-1} q_i C_{k-i} -sum_{i=k+1} ^ n p_{n-i+1} C_{i-k} ]

    可以发现,两项都是卷积的形式,令(A=q imes C)(B=p imes C),则(E_k=A_k-B_{n-k+1})

    于是直接上(FTT)即可,时间复杂度(O(n log n))

    Code:

    #include<bits/stdc++.h>
    #define Pi acos(-1.0)
    using namespace std;
    const int N=4e5+11;
    int n,m,k,len=1,tim,p[N];
    struct Complex{double x,y;}a[N],b[N],c[N];
    Complex operator + (Complex A,Complex B){return (Complex){A.x+B.x,A.y+B.y};}
    Complex operator - (Complex A,Complex B){return (Complex){A.x-B.x,A.y-B.y};}
    Complex operator * (Complex A,Complex B){return (Complex){A.x*B.x-A.y*B.y,A.x*B.y+A.y*B.x};}
    int read(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
        while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
        return x*f;
    }
    void FFT(Complex *v,int flag){
        for(int i=0;i<len;i++)
            if(i<p[i]) swap(v[i],v[p[i]]);
        for(int l=2;l<=len;l<<=1){
            Complex wn=(Complex){cos(flag*2*Pi/l),sin(flag*2*Pi/l)};
            for(int st=0;st<len;st+=l){
                Complex w=(Complex){1,0};
                for(int u=st;u<st+(l>>1);u++,w=w*wn){
                    Complex x=v[u],y=w*v[u+(l>>1)];
                    v[u]=x+y;v[u+(l>>1)]=x-y;
                }    
            }
        }
    }
    signed main(){
        n=read();++n;
        for(int i=1;i<n;i++) scanf("%lf",&a[i].x);
        for(int i=1;i<n;i++) b[i].x=a[n-i].x;
        for(int i=1;i<n;i++) c[i].x=(double)1.0/(double)i/(double)i;
        while(len<=max(n,m)*2) len=len<<1,++tim;
        for(int i=0;i<len;i++)
            p[i]=(p[i>>1]>>1)|((i&1)<<(tim-1));
        FFT(a,1);FFT(b,1);FFT(c,1);
        for(int i=0;i<len;i++) a[i]=a[i]*c[i],b[i]=b[i]*c[i];
        FFT(a,-1);FFT(b,-1);
        for(int i=0;i<len;i++) a[i].x=a[i].x/len,b[i].x=b[i].x/len;
        for(int i=1;i<n;i++) printf("%lf
    ",a[i].x-b[n-i].x);
        return 0;
    }
    
    
  • 相关阅读:
    Shell特殊变量:Shell $0, $#, $*, $@, $?, $$和命令行参数
    linux命令学习7-jstat命令
    linux命令学习6-dpkg命令
    PSSH 批量管理服务器
    堆排序 (Heap Sort)
    极客时间-左耳听风-程序员攻略-程序员修养
    应急响应-GHO提取注册表快照
    nc替代技术方案
    从无文件技术到使用隐写术:检查Powload的演变
    CVE-2019-0797漏洞:Windows操作系统中的新零日在攻击中被利用
  • 原文地址:https://www.cnblogs.com/NLDQY/p/12239919.html
Copyright © 2020-2023  润新知