UVALive - 6886 Golf Bot 多项式乘法(FFT)
题目链接:
http://acm.hust.edu.cn/vjudge/problem/129724
Golf Bot
Time Limit: 15000MS
题意
给你n个数,m个查询,对于每个查询,问能不能用n个数中的一个或两个(同一个数可以取两次)相加凑出来。
题解
多项式乘法,用快速傅里叶变化加速,时间复杂度:O(nlogn)。
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;
const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0);
const int maxn=555555;
int vis[maxn],n;
struct Complex {
double real, image;
Complex(double real, double image):real(real),image(image) {}
Complex() {}
friend Complex operator + (const Complex &c1, const Complex &c2) {
return Complex(c1.real + c2.real, c1.image + c2.image);
}
friend Complex operator - (const Complex &c1, const Complex &c2) {
return Complex(c1.real - c2.real, c1.image - c2.image);
}
friend Complex operator * (const Complex &c1, const Complex &c2) {
return Complex(c1.real*c2.real - c1.image*c2.image, c1.real*c2.image + c1.image*c2.real);
}
}a[maxn];
struct IterativeFFT {
Complex A[maxn];
int rev(int id, int len) {
int ret = 0;
for(int i = 0; (1 << i) < len; i++) {
ret <<= 1;
if(id & (1 << i)) ret |= 1;
}
return ret;
}
//当DFT= 1时是DFT, DFT = -1则是逆DFT
//对长度为len(2的幂)的数组进行DFT变换
void FFT(Complex *a,int len, int DFT) {
for(int i = 0; i < len; i++)
A[rev(i, len)] = a[i];
for(int s = 1; (1 << s) <= len; s++) {
int m = (1 << s);
Complex wm = Complex(cos(DFT*2*PI/m), sin(DFT*2*PI/m));
//这一层结点的包含数组元素个数都是(1 << s)
for(int k = 0; k < len; k += m) {
Complex w = Complex(1, 0);
//折半引理, 根据两个子节点计算父亲节点
for(int j = 0; j < (m >> 1); j++) {
Complex t = w*A[k + j + (m >> 1)];
Complex u = A[k + j];
A[k + j] = u + t;
A[k + j + (m >> 1)] = u - t;
w = w*wm;
}
}
}
if(DFT == -1) for(int i = 0; i < len; i++) A[i].real /= len, A[i].image /= len;
for(int i=0; i<len; i++) a[i]=A[i];
}
} myfft;
void init() {
rep(i,0,maxn) a[i]=Complex(0,0);
a[0].real=1;
clr(vis,0);
}
int main() {
while(scanf("%d",&n)==1&&n) {
init();
int ma=0;
rep(i,0,n){
int x;
scanf("%d",&x);
ma=max(ma,x);
a[x].real=1.0;
}
int len=1;
while(len<ma) len<<=1;
len<<=1;
myfft.FFT(a, len, 1);
rep(i,0,len){
a[i]=a[i]*a[i];
}
myfft.FFT(a,len,-1);
rep(i,0,len){
if(a[i].real>eps) vis[i]=1;
}
int q;
scanf("%d",&q);
int ans=0;
while(q--) {
int x;
scanf("%d",&x);
if(vis[x]) {
ans++;
}
}
printf("%d\n",ans);
}
return 0;
}
这题用bitset也能做,不过跑的没有FFT快。
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;
const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0);
//start----------------------------------------------------------------------
const int maxn=222223;
bitset<maxn> bset1,bset2;
int arr[maxn];
int n;
int main() {
while(scanf("%d",&n)==1&&n){
bset1.reset();
rep(i,0,n){
scanf("%d",&arr[i]);
bset1.set(arr[i]);
}
bset2=bset1;
rep(i,0,n){
bset1|=bset2<<arr[i];
}
int q; scanf("%d",&q);
int ans=0;
while(q--){
int x; scanf("%d",&x);
if(bset1.test(x)) ans++;
}
printf("%d\n",ans);
}
return 0;
}
//end-----------------------------------------------------------------------
UVALive - 6886 Golf Bot 多项式乘法(FFT)的更多相关文章
- UVALive 6886 Golf Bot FFT
Golf Bot 题目连接: http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=129724 Description Do ...
- 多项式乘法(FFT)学习笔记
------------------------------------------本文只探讨多项式乘法(FFT)在信息学中的应用如有错误或不明欢迎指出或提问,在此不胜感激 多项式 1.系数表示法 ...
- 【learning】多项式乘法&fft
[吐槽] 以前一直觉得这个东西十分高端完全不会qwq 但是向lyy.yxq.yww.dtz等dalao们学习之后发现这个东西的代码实现其实极其简洁 于是趁着还没有忘记赶紧来写一篇博 (说起来这篇东西的 ...
- 洛谷.3803.[模板]多项式乘法(FFT)
题目链接:洛谷.LOJ. FFT相关:快速傅里叶变换(FFT)详解.FFT总结.从多项式乘法到快速傅里叶变换. 5.4 又看了一遍,这个也不错. 2019.3.7 叕看了一遍,推荐这个. #inclu ...
- @总结 - 1@ 多项式乘法 —— FFT
目录 @0 - 参考资料@ @1 - 一些概念@ @2 - 傅里叶正变换@ @3 - 傅里叶逆变换@ @4 - 迭代实现 FFT@ @5 - 参考代码实现@ @6 - 快速数论变换 NTT@ @7 - ...
- [uoj#34] [洛谷P3803] 多项式乘法(FFT)
新技能--FFT. 可在 \(O(nlogn)\) 时间内完成多项式在系数表达与点值表达之间的转换. 其中最关键的一点便为单位复数根,有神奇的折半性质. 多项式乘法(即为卷积)的常见形式: \[ C_ ...
- UOJ 34 多项式乘法 FFT 模板
这是一道模板题. 给你两个多项式,请输出乘起来后的多项式. 输入格式 第一行两个整数 nn 和 mm,分别表示两个多项式的次数. 第二行 n+1n+1 个整数,表示第一个多项式的 00 到 nn 次项 ...
- [HNOI2017] 礼物 - 多项式乘法FFT
题意:给定两个 \(n\) 元环,环上每个点有权值,分别为 \(x_i, y_i\).定义两个环的差值为 \[\sum_{i=0}^{n-1}{(x_i-y_i)^2}\] 可以旋转其中的一个环,或者 ...
- 【Luogu3808】多项式乘法FFT(FFT)
题目戳我 一道模板题 自己尝试证明了大部分... 剩下的还是没太证出来... 所以就是一个模板放在这里 以后再来补东西吧.... #include<iostream> #include&l ...
随机推荐
- 【读书笔记 - Effective Java】04. 通过私有构造器强化不可实例化的能力
工具类(utility class)不希望被实例化,比如只包含静态方法和静态域的类.为了这个目的,需要让这个类包含一个私有构造器. // 私有构造器示例 public class UtilityCla ...
- php源码建博客2--实现单入口MVC结构
主要: MVC目录结构 数据库工具类制作 创建公共模型类和公共控制器类 --------------文件结构:-------------------------------------- blog├─ ...
- Leecode刷题之旅-C语言/python-121买卖股票的最佳时机
/* * @lc app=leetcode.cn id=121 lang=c * * [121] 买卖股票的最佳时机 * * https://leetcode-cn.com/problems/best ...
- Go搭建一个博客系统
go语言环境就不用多说了,版本肯定越高越好,这里用go1.10 先放着
- Java基础之进制转换
1.十进制与二进制之间的转换 (1)十进制转二进制的方法:使用十进制的数据不断除以2,直到商为0为止,从下往上取余就是对应的二进制. (2)二进制转十进制:使用二进制的每一位乘以2的n次方,n从0开始 ...
- MySQL高级第三章——查询截取分析
一.查询分析 1.永远小表驱动大表 使用小的数据集驱动大的数据集. //复习 EXISTS 的知识:SELECT ... FROM tb WHERE EXISTS (subquery) 是因为前后数据 ...
- 全国各大城市Uber客服联系方式(电话、邮箱、微博)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- GDAL中GDALDataset::RasterIO分块读取的实现
GDALDataset类中的RasterIO函数能够对图像任意指定区域.任意波段的数据按指定数据类型.指定排列方式读入内存和写入文件中,因此可以实现对大影像的分块读.写运算操作.针对特大的影像图像,有 ...
- docker社区的geodata/gdal镜像dockerfile分析
对应从事遥感与地理信息的同仁来说,gdal应该是所有工具中使用频度最高的库了,那么在docker中使用gdal时,面临的第一步就是构建gdal基础镜像,社区中引用最多的就是geodata提供的gdal ...
- 学会了vim中的自动补全功能
好开心,再也不用再多个工具之间切换了,哈哈 擦,功能太弱