UVALive_6886_Golf Bot(FFT快速傅裡葉變換)

來源:互聯網
上載者:User

傳送門:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=77958#problem/C


題型:數論


題意:

       集合A中取1個數或者2個數,其和變成一個新的集合S。q次查詢,每次查詢輸入一個數,問q個數中有多少個數屬於集合S。

      集合A元素個數2e5,q<=2e5,A元素大小<=2e5,查詢數字2e5


分析:

暴力枚舉O(C(n,2)+n),O(n^2)複雜度過高。

FFT統計出現了哪些數,然後直接算結果就ok,複雜度O(nlogn)。

只取1個數只需要O(n)標記一下,S1 = {1,3,5}。

下面討論取2個數的情況:

例如A = {1,3,5}

設多項式


則S2 = {2,4,6,8,10}

綜上:S={1,2,3,4,5,6,8,10}


代碼;

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define mt(a,b) memset(a,b,sizeof(a))using namespace std;const int M = 201000;struct Complex {    double x,y;    Complex(double _x=0,double _y=0) {        x=_x;        y=_y;    }    friend Complex operator -(const Complex &a,const Complex &b) {        return Complex(a.x-b.x,a.y-b.y);    }    friend Complex operator +(const Complex &a,const Complex &b) {        return Complex(a.x+b.x,a.y+b.y);    }    friend Complex operator *(const Complex &a,const Complex &b) {        return Complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);    }};class FFT {    Complex u,t;    void change(Complex y[],int len) {        for(int i=1,j=len>>1,k; i<len-1; i++) {            if(i<j) swap(y[i],y[j]);            k=len>>1;            while(j>=k) {                j-=k;                k>>=1;            }            if(j<k) j+=k;        }    }public:    void fft(Complex y[],int len,int on) {        change(y,len);        double tmp=-on*2*acos(-1.0);        for(int h=2; h<=len; h<<=1) {            Complex wn(cos(tmp/h),sin(tmp/h));            for(int j=0; j<len; j+=h) {                Complex w(1,0);                int h2=h>>1;                for(int k=j; k<j+h2; k++) {                    u=y[k];                    t=w*y[k+h2];                    y[k]=u+t;                    y[k+h2]=u-t;                    w=w*wn;                }            }        }        if(on==-1) {            for(int i=0; i<len; i++) {                y[i].x/=len;            }        }    }} g;int flag[M*4];Complex x[M*4];int a[M*2];int main() {    int n,q;    while(~scanf("%d",&n)) {        mt(flag,0);        int maxn = 0;        for(int i=0; i<n; i++) {            scanf("%d",&a[i]);            flag[a[i]] = 1;            maxn = max(maxn,a[i]);        }        int len = 1;        maxn<<=1;        while(len<maxn) len<<=1;        for(int i=0; i<len; i++) {            x[i] = Complex(flag[i],0);        }        g.fft(x,len,1);        for(int i=0;i<len;i++){            x[i] = x[i]*x[i];        }        g.fft(x,len,-1);        mt(flag,0);        for(int i=0;i<n;i++){            flag[a[i]]++;        }        for(int i=0;i<len;i++){            flag[i] += (int)(x[i].x+0.5);        }//        for(int i=0;i<len;i++){//            printf("%d--->%d\n",i,flag[i]);//        }        scanf("%d",&q);        int b;        int ans = 0;        while(q--){            scanf("%d",&b);            if(flag[b]) ans++;        }        printf("%d\n",ans);    }    return 0;}/**31356245789*/


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.