zoukankan      html  css  js  c++  java
  • UVA12879 Golf Bot

    UVA12879 Golf Bot

    给定n个数 ai 和 m个数 bi
    问ai+aj=bk的组数

    Solution

    暴力很好想, (O(n^{2})) 枚举ai
    FFT可以让我们在 (nlogn) 的时间把多项式相乘
    同底的数相乘,指数相加
    所以我们把出现过的那一项的系数设为非零, 自己相乘, 得到的非零项就是加出来的数
    然后观察下数据不用离散化

    Code

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #include<climits>
    #include<cmath>
    #define LL long long
    #define REP(i, x, y) for(int i = (x);i <= (y);i++)
    using namespace std;
    int RD(){
        int out = 0,flag = 1;char c = getchar();
        while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
        while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
        return flag * out;
        }
    
    using namespace std;
    const int MAXN=1e7+10;
    inline int read()
    {
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    const double Pi=acos(-1.0);
    struct complex
    {
        double x,y;
        complex (double xx=0,double yy=0){x=xx,y=yy;}
    }a[MAXN];
    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 N,M;
    int l,r[MAXN];
    int limit=1;
    void FFT(complex *A,int type)
    {
        for(int i=0;i<limit;i++) 
            if(i<r[i]) swap(A[i],A[r[i]]);//求出要迭代的序列 
        for(int mid=1;mid<limit;mid<<=1)//待合并区间的中点
        {
            complex Wn( cos(Pi/mid) , type*sin(Pi/mid) ); //单位根 
            for(int R=mid<<1,j=0;j<limit;j+=R)//R是区间的右端点,j表示前已经到哪个位置了 
            {
                complex w(1,0);//幂 
                for(int k=0;k<mid;k++,w=w*Wn)//枚举左半部分 
                {
                     complex x=A[j+k],y=w*A[j+mid+k];//蝴蝶效应 
                    A[j+k]=x+y;
                    A[j+mid+k]=x-y;
                }
            }
        }
    }
    int MAX;
    void init(){
    	REP(i, 0, MAXN - 1)a[i].x = a[i].y = r[i] = 0;
    	limit = 1, l = 0, MAX = 0;
    	}
    void work(){
    	a[0].x = 1;
    	REP(i, 1, N){
    		int Index = RD();
    		a[Index].x = 1;
    		MAX = max(MAX, Index);
    		}
    	while(limit <= MAX + MAX)limit <<= 1, l++;
    	REP(i, 0, limit - 1) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
    	FFT(a, 1);
    	REP(i, 0, limit - 1)a[i] = a[i] * a[i];
    	FFT(a, -1);
    	M = RD();
    	int ans = 0;
    	REP(i, 1, M){
    		int ask = RD();
    		if((int)(a[ask].x / limit + 0.5))ans++;
    		}
    	cout<<ans<<endl;
    	}
    int main(){
    	while(~scanf("%d", &N)){
    		init();
    		work();
    		}
        return 0;
    	}
    
  • 相关阅读:
    Leetcode 109
    Leetcode 118
    js时间操作
    DWR搭建以及使用教程
    Ant 概念
    Eclipse 快捷键
    [eclipse] 三个操作技巧
    js call方法
    js验证密码强弱
    request getParameter getAttribute
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/14657242.html
Copyright © 2011-2022 走看看