大致题意:

给你N个整数和M个整数,问这M个数中,有几个数可以表达成那N个整数中一个或者两个整数的和。

分析:

算是半个裸的FFT。FFT可以用来在nlongn时间内求高精度乘法,我们先模拟一下乘法。

A4A3A2A1A0*B4B3B2B1B0  Ai,Bj表示位数,结果保存在Ck中

4   3   2   1   0(下标)

A4 A3 A2 A1 A0

B4 B3 B2 B1 B0

先不考虑进位

那么C0=A0*B0

C1=A0*B1+A1*B0

Ck=sum(Ai*Bj) (i+j=k)

我们现在看题目是求两个数或者一个数的和是否能在M中匹配到。与上式对比,发现了共同点,i,j的和的下标对应的值即Ck,也就是说我们可以把出现的数字当做位置,出现的位置赋值为1,没有为0,第0位为1,因为可以加0嘛。

样例如下

       5 4 3 2 1 0(下标)

       1 0 1 0 1 1

X            1 0 1 0 1 1

=  1 0 2 0 3 2 2 2 1 2 1

A 9 8 7 6 5 4 3 2 1 0(下标)

结果不需要再进位,只要k下标对应的值大于0就符合条件。

#include <bits/stdc++.h>
using namespace std; const double PI = acos(-1.0);
struct Complex
{
double x, y;
Complex(double _x = 0.0, double _y = 0.0)
{
x = _x;
y = _y;
}
Complex operator - (const Complex &b)const
{
return Complex(x-b.x, y-b.y);
}
Complex operator + (const Complex &b)const
{
return Complex(x+b.x, y+b.y);
}
Complex operator * (const Complex &b)const
{
return Complex(x*b.x-y*b.y, x*b.y+y*b.x);
}
}; void change(Complex y[], int len)
{
int i, j, k;
for(i = 1, j = len/2; i < len-1; i++)
{
if (i < j) swap(y[i], y[j]);
k = len/2;
while(j >= k)
{
j -= k;
k /= 2;
}
if (j < k) j += k;
}
} void fft(Complex y[], int len, int on)
{
change(y, len);
for(int h = 2; h <= len; h <<= 1)
{
Complex wn(cos(-on*2*PI/h), sin(-on*2*PI/h));
for(int j = 0; j < len; j += h)
{
Complex w(1, 0);
for(int k = j; k < j+h/2; k++)
{
Complex u = y[k];
Complex t = w*y[k+h/2];
y[k] = u+t;
y[k+h/2] = u-t;
w = w*wn;
}
}
}
if (on == -1)
for(int i = 0; i < len; i++)
y[i].x /= len;
} const int maxn=4*200010;
Complex x1[maxn],x2[maxn];
int a[maxn/4];
int sum[maxn]; int main()
{
int N,M;
while(~scanf("%d",&N))
{
memset(a,0,sizeof(a));
int len1=0;
for(int i=0; i<N; i++)
{
int tmp;
scanf("%d",&tmp);
a[tmp]=1;
len1=max(len1,tmp);
}
len1++;
int len=1;
while(len < len1*2) len<<=1;
a[0]=1;
for(int i=0; i<len1; i++)
x1[i]=Complex(a[i],0);
for(int i=0; i<len1; i++)
x2[i]=Complex(a[i],0);
for(int i=len1; i<len; i++)
x2[i]=Complex(0,0);
fft(x1,len,1);
fft(x2,len,1);
for(int i=0; i<len; i++)
x1[i]=x1[i]*x2[i];
fft(x1,len,-1);
for(int i=0; i<len; i++)
sum[i]=(int)(x1[i].x+0.5);
scanf("%d",&M);
len=2*len1-1;
int cnt=0;
for(int i=0;i<M;i++)
{
int t;
scanf("%d",&t);
if(sum[t]>0) cnt++;
}
printf("%d\n",cnt);
}
return 0;
}

Gym 100783C Golf Bot FFT的更多相关文章

  1. UVALive 6886 Golf Bot FFT

    Golf Bot 题目连接: http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=129724 Description Do ...

  2. UVALIVE6886 Golf Bot (FFT)

    题意:打高尔夫 给你n个距离表示你一次可以把球打远的距离 然后对于m个询问 问能否在两杆内把球打进洞 题解:平方一下就好 注意一下x0的系数为1表示打一杆 才发现数组应该开MAXN * 4 之前写的题 ...

  3. LA6886 Golf Bot(FFT)

    题目 Source https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page= ...

  4. UVALive - 6886 Golf Bot 多项式乘法(FFT)

    题目链接: http://acm.hust.edu.cn/vjudge/problem/129724 Golf Bot Time Limit: 15000MS 题意 给你n个数,m个查询,对于每个查询 ...

  5. HNU11376:Golf Bot

    Problem description Input The first line has one integer: N, the number of different distances the G ...

  6. Gym100783C Golf Bot(FFT)

    https://vjudge.net/problem/Gym-100783C 题意: 给出n个数,然后有m次查询,每次输入一个数x,问x能否由n个数中2个及2个以下的数相加组成. 思路:题意很简单,但 ...

  7. [Swerc2014 C]Golf Bot

    题意:给你N个数字,每次利用这N个数字中最多两个数字进行加法运算,来得到目标中的M个数字. Solution: 我们先来看看多项式乘法:\(A(x)=\sum_{i=0}^{n-1}a_ix^i\), ...

  8. FFT题集

    FFT学习参考这两篇博客,很详细,结合这看,互补. 博客一 博客二 很大一部分题目需要构造多项式相乘来进行计数问题. 1. HDU 1402 A * B Problem Plus 把A和B分别当作多项 ...

  9. Codeforces Gym 100803D Space Golf 物理题

    Space Golf 题目连接: http://codeforces.com/gym/100803/attachments Description You surely have never hear ...

随机推荐

  1. Linux PATH环境变量及作用(初学者必读)

    Linux PATH环境变量及作用(初学者必读) < 什么是环境变量,Linux环境变量有哪些?Linux打包(归档)和压缩 > <Linux就该这么学>是一本基于最新Linu ...

  2. 命令stat anaconda-ks.cfg会显示出文件的三种时间状态(已加粗):Access、Modify、Change。这三种时间的区别将在下面的touch命令中详细详解:

    7.stat命令 stat命令用于查看文件的具体存储信息和时间等信息,格式为"stat 文件名称". stat命令可以用于查看文件的存储信息和时间等信息,命令stat anacon ...

  3. dstat命令

    dstat命令 dstat命令是一个用来替换vmstat.iostat.netstat.nfsstat和ifstat这些命令的工具,是一个全能系统信息统计工具.与sysstat相比,dstat拥有一个 ...

  4. mysql示例及练习2

    #创建数据库并应用create database shopdb;use shopdb;#创建表customerscreate table customers(c_id int primary key ...

  5. 第7讲 | ICMP与ping:投石问路的侦察兵

    第7讲 | ICMP与ping:投石问路的侦察兵 ping 是基于 ICMP 协议工作的.ICMP 全称 Internet Control Message Protocol,就是互联网控制报文协议. ...

  6. 一:windows10开启虚拟化服务(也可用于部署docker提前准备)

    查看虚拟化已开启: 如果未启用,则需要添加虚拟化功能:控制面板 -> 启用或关闭Windows功能 选择Hyper-V的所有功能,确定: 系统会自动搜索并安装功能.安装完毕即可. 完结,撒花~~

  7. 原子层沉积(ALD)和化学气相沉积(CVD)微电子制造铜金属化的研究进展

    原子层沉积(ALD)和化学气相沉积(CVD)微电子制造铜金属化的研究进展 Atomic Layer Deposition (ALD) and Chemical Vapor Deposition (CV ...

  8. 稀疏性如何为AI推理增加难度

    稀疏性如何为AI推理增加难度 NVIDIA Ampere架构使数学运算加倍,以加速对各种神经网络的处理. 如果曾经玩过游戏Jenga,那么将有一些AI稀疏感. 玩家将木制积木交叉成一列.然后,每个玩家 ...

  9. 在NVIDIA A100 GPU中使用DALI和新的硬件JPEG解码器快速加载数据

    在NVIDIA A100 GPU中使用DALI和新的硬件JPEG解码器快速加载数据 如今,最流行的拍照设备智能手机可以捕获高达4K UHD的图像(3840×2160图像),原始数据超过25 MB.即使 ...

  10. CUDA统一内存分析

    CUDA统一内存分析 PascalMIG 如 NVIDIA Titan X 和 NVIDIA Tesla P100 是第一个包含页 GPUs 定额引擎的 GPUs ,它是统一内存页错误处理和 MIG ...