zoukankan      html  css  js  c++  java
  • CF993E Nikita and Order Statistics

    小于x的赋值为1,否则为0

    区间等于k的个数

    求0~n连续的n+1个k?

    N<=1e5?

    FFT!

    考虑卷积建模:用下标相加实现转移到位,数值相乘类比乘法原理!

    法一:

    分治,然后FFT没了

    法二:

    不分治也可以!区间查询->前缀相减

    ans[j-i]=f[j]*f[i],f[i]表示数值为i的前缀和个数

    减法怎么办?
    reverse变成加法!

    i->n-i

    ans[j-i]=f[j]*f[i]=f[j]*f'[n-i]

    FFT一下,n+j-i位置的值就是ans辣

    #include<bits/stdc++.h>
    #define reg register int
    #define il inline
    #define numb (ch^'0')
    using namespace std;
    typedef long long ll;
    il void rd(int &x){
        char ch;x=0;bool fl=false;
        while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=numb;isdigit(ch=getchar());x=x*10+numb);
        (fl==true)&&(x=-x);
    }
    namespace Miracle{
    const double Pi=acos(-1);
    const int N=2e5+5;
    struct po{
        double x,y;
        po(){}
        po(double xx,double yy){
            x=xx;y=yy;
        }
        po friend operator +(po a,po b){
            return po(a.x+b.x,a.y+b.y);
        }
        po friend operator -(po a,po b){
            return po(a.x-b.x,a.y-b.y);
        }
        po friend operator *(po a,po b){
            return po(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
        }
    }a[4*N],b[4*N];
    int c[N],s[N];
    int n,x;
    int rev[4*N];
    ll ans[N];
    void fft(po *f,int c){
        for(reg i=0;i<n;++i){
            if(i<rev[i]) swap(f[i],f[rev[i]]);
        }
        for(reg p=2;p<=n;p<<=1){
            po gen;int len=p/2;
            gen=po(cos(Pi/len),c*sin(Pi/len));
            for(reg l=0;l<n;l+=p){
                po buf=po(1.0,0.0);
                for(reg k=l;k<l+len;++k){
                    po tmp=f[k+len]*buf;
                    f[k+len]=f[k]-tmp;
                    f[k]=f[k]+tmp;
                    buf=buf*gen;
                }
            }
        }
    }
    int main(){
        rd(n);rd(x);
        int lp=n;
        for(reg i=1;i<=n;++i) {
            rd(c[i]);c[i]=c[i]<x;
            s[i]=s[i-1]+c[i];
            ++a[s[i]].x;
        }
        ++a[s[0]].x;
        for(reg i=0;i<=n;++i){
            b[i].x=a[n-i].x;
        }
        int m;
        for(m=2*n,n=1;n<=m;n<<=1);
        for(reg i=0;i<n;++i){
            rev[i]=(rev[i>>1]>>1)|((i&1)?(n>>1):0);
        }
    //    for(reg i=1;i<=lp;++i){
    //        cout<<c[i]<<" ";
    //    }cout<<endl;
    //    for(reg i=0;i<n;++i){
    //        cout<<a[i].x<<" ";
    //    }cout<<endl;
    //    for(reg j=0;j<n;++j){
    //        cout<<b[j].x<<" ";
    //    }cout<<endl;
        fft(a,1);
        fft(b,1);
        for(reg i=0;i<n;++i) b[i]=a[i]*b[i];
        fft(b,-1);
        for(reg i=0;i<=lp;++i) ans[i]=round(b[lp-i].x/n);
        //cout<<" ans[0] "<<ans[0]<<endl;
        ans[0]=(ans[0]+(lp+1))/2-(lp+1);
        for(reg i=0;i<=lp;++i){
            printf("%lld ",ans[i]);
        }
        return 0;
    }
    
    }
    signed main(){
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
       Date: 2018/12/27 9:01:58
    */

    reverse想法比较有意思!

    值得注意!

  • 相关阅读:
    如何处理iOS中照片的方向
    Builder Pattern 在 Objective-C 中的使用
    多线程(三)-- 线程安全问题
    多线程(二)--NSThread基本使用
    多线程 (一)
    报错:Request failed: unacceptable content-type: text/html
    Cocoapods简单安装和使用
    Objective
    Objective
    Python学习笔记(一)--注释
  • 原文地址:https://www.cnblogs.com/Miracevin/p/10186902.html
Copyright © 2011-2022 走看看