BZOJ4836: [Lydsy1704月赛]二元运算-分治FFT
传送门
题意:
定义二元运算 opt 满足
x \ opt \ y =\left\{\begin{aligned}x+y&,&x
现在给定一个长为 n 的数列 a 和一个长为 m 的数列 b ,接下来有 q 次询问。每次询问给定一个数字 c
你需要求出有多少对 (i, j) 使得 ai opt bj=caioptbj=ca_i\ opt\ b_j=c 。
Solution:
首先我们抛开限制来看:
如果只考虑加法的话,对于每个询问k,ans=∑ki=0ai∗bk−ians=∑i=0kai∗bk−ians=\sum_{i=0}^ka_i*b_{k-i}
只考虑减法的话,对于每个询问k,ans=∑ni=kai∗bi−kans=∑i=knai∗bi−kans=\sum_{i=k}^na_i*b_{i-k}
我们将a数组翻转后可以得到ans=∑ni=kan−i∗bi−k=∑n−ki=0ai∗bn−k−ians=∑i=knan−i∗bi−k=∑i=0n−kai∗bn−k−ians=\sum_{i=k}^na_{n-i}*b_{i-k}=\sum_{i=0}^{n-k}a_i*b_{n-k-i}
但是,由于有大小限制,所以说不能简单地FFT
对于加法的情况,可能会计算到x≥yx≥yx≥y的情况,而对于减法则不会
所以说我们只需要对加法情况进行分治FFT,对减法情况只需要一次FFT即可求出所有答案
关于分治FFT,具体就是每次对于[l,r][l,r][l,r]这段区间,处理a[l,mid]a[l,mid]a[l,mid]和b[mid+1,r]b[mid+1,r]b[mid+1,r]即可
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std;
const double pi=acos(-1);
int n,m,T,q,a[50010],b[50010],maxn;
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);}
}a1[2*65540],a2[2*65540];
long long ans[200010];
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>>=1;if (j<k) j+=k;}
}
void FFT(complex y[],int len,int ifi)
{change(y,len);for (int h=2;h<=len;h<<=1){complex wn(cos(2*pi*ifi/h),sin(2*pi*ifi/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 v=w*y[k+h/2];y[k]=u+v;y[k+h/2]=u-v;w=w*wn;}}}if (ifi==-1) for (int i=0;i<len;i++) y[i].x/=len;
}
void solve(int l,int r)
{int mid=l+r>>1;if (l==r) {//ans[0]+=a[l]*b[r];return;}solve(l,mid);solve(mid+1,r);int len=1;while (len<=r-l+1) len<<=1;for (int i=l;i<=mid;i++) a1[i-l]=complex(a[i],0);for (int i=mid-l+1;i<len;i++) a1[i]=complex(0,0);for (int i=mid+1;i<=r;i++) a2[i-mid-1]=complex(b[i],0);for (int i=r-mid;i<len;i++) a2[i]=complex(0,0);FFT(a1,len,1);FFT(a2,len,1);for (int i=0;i<len;i++) a1[i]=a1[i]*a2[i];FFT(a1,len,-1);for (int i=0;i<len;i++) ans[i+l+mid+1]+=(long long)(a1[i].x+0.5);
}
int main()
{
// freopen("4836.in","r",stdin);
// freopen("4836.out","w",stdout);scanf("%d",&T);while (T--){memset(a,0,sizeof(a));memset(b,0,sizeof(b));memset(ans,0,sizeof(ans));scanf("%d%d%d",&n,&m,&q);for (int x,i=1;i<=n;i++) scanf("%d",&x),a[x]++,maxn=max(maxn,x);for (int x,i=1;i<=m;i++) scanf("%d",&x),b[x]++,maxn=max(maxn,x);solve(0,maxn);int len=1;while (len<=2*maxn) len<<=1;for (int i=0;i<=maxn;i++) a1[maxn-i]=complex(a[i],0);for (int i=maxn+1;i<len;i++) a1[i]=complex(0,0);for (int i=0;i<=maxn;i++) a2[i]=complex(b[i],0);for (int i=maxn+1;i<len;i++) a2[i]=complex(0,0);// for (int i=0;i<len;i++) printf("%d ",(long long)(a1[i].x+0.5));cout<<endl;// for (int i=0;i<len;i++) printf("%d ",(long long)(a2[i].x+0.5));cout<<endl;FFT(a1,len,1);FFT(a2,len,1);for (int i=0;i<len;i++) a1[i]=a1[i]*a2[i];FFT(a1,len,-1);//for (int i=0;i<len;i++) printf("%d ",(long long)(a1[i].x+0.5));cout<<endl;for (int i=0;i<=maxn;i++) ans[maxn-i]+=(long long)(a1[i].x+0.5);for (int x,i=1;i<=q;i++)scanf("%d",&x),printf("%lld\n",ans[x]);}
}
BZOJ4836: [Lydsy1704月赛]二元运算-分治FFT相关推荐
- (2016北京集训十)【xsy1529】小Q与进位制 - 分治FFT
题意很简单,就是求这个数... 其实场上我想出了分治fft的正解...然而不会打...然后打了个暴力fft挂了... 没啥好讲的,这题很恶心,卡常卡精度还爆int,要各种优化,有些dalao写的很复杂 ...
- 【学习笔记】分治FFT
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 分治FFT 1. Luogu P4721 [模板]分治 FFT 2. 2020 ICPC Mac ...
- 2020 ICPC Macau A. Accelerator(期望,计数,分治FFT)(每日一题 21.7.6)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 2020 ICPC Macau A. Accelerator(分治FFT) Problem 给定长度为 ...
- [洛谷P4721]【模板】分治 FFT
题目大意:给定长度为$n-1$的数组$g_{[1,n)}$,求$f_{[0,n)}$,要求: $$ f_i=\sum_{j=1}^if_{i-j}g_j\\ f_0=1 $$ 题解:直接求复杂度是$O ...
- [分治FFT]「CTSC2018」青蕈领主
题目梗概 定义一个序列是连续的,当且仅当这个序列的最大值-最小值不超过序列长度-1. 现在有一个长度为\(n\)的排列,给出以每个位置为右端点的最长连续区间的长度,求满足的排列的方案数. 解题思路 如 ...
- 洛谷 - P4721 【模板】分治 FFT(分治NTT)
题目链接:点击查看 题目大意:给出序列 g1,⋯,ng_{1,\cdots,n}g1,⋯,n,求 f0,⋯,nf_{0,\cdots,n}f0,⋯,n 规定 fi=∑j=1ifi−jgjf_i=\ ...
- HDU5322 - cdq分治FFT加速dp
5322 Hope [CDQ分治FFT加速计算dp] 题意 每一个每一个排列,排列中每个数向它后面第一个比它大的数连一条边. 每个排列对于答案的贡献是这个排列所生成的图中的每一个联通量中点的个数的平方 ...
- 【牛客 - 157F】三轮(dp,分治fft)
题干: 链接:https://ac.nowcoder.com/acm/contest/157/F 来源:牛客网 小k有一个三轮,它最多可以装105大小的东西 小k有n种商品,他要准备出摊了 每种商品体 ...
- FTT NTT 分治FFT
FFT study from: http://www.orchidany.cf/2019/02/19/FFT1/ https://www.cnblogs.com/zwfymqz/p/8244902.h ...
- 【集训队作业2018】青春猪头少年不会梦到兔女郎学姐(容斥)(分治FFT)
简要题意: 给定 nnn 种颜色的球,第 iii 种颜色的球数量为 aia_iai 个,一种排列的贡献可以如下计算:先把这个序列首尾相连,然后把所有相邻且颜色相同的段拿出来,贡献为他们的长度之积,求 ...
最新文章
- ssh(Struts+spring+Hibernate)三大框架整合-简述
- MySQL两种表存储结构MyISAM和InnoDB的性能比较测试
- 倒序排序_排序算法(六):Counting Sort 计数排序
- linux内核研究(二)
- centos系统设置局域网静态IP
- MySQL8增量备份1008无标题_mysql增量备份
- 52. yii create webapp
- CentOS8下vi编辑器常用命令
- 国产杂牌机java_国货精品 山寨 杂牌 HiPhone 诺卡 MTK联发科 mrp
- 【字符串】13. 罗马数字转整数
- jq实现点击复制文本功能
- PCB多层板的一些资料
- logutils java_【java】简单的日志工具类LogUtils
- nginx: [warn] conflicting server name locahost on 0.0.0.0:80, ignored
- java中put是什么意思_关于java:请求参数和PUT方法
- cesium粒子特效
- FileZilla Client下载安装
- [人工智能-深度学习-81]:视觉 - 视频换脸软件大全
- Excel VBA 代替Sumproduct实现多条件求和
- 微信小程序项目实例——二维码生成器
热门文章
- 今日头条 推荐机制实现
- J2EE配置文件加密
- 十年MFC经历认识的Microsoft技术
- Linux进程虚拟内存大 性能,Linux进程分析(一) 虚拟内存和物理内存
- Java代码复用的三种常用方式:继承、组合和代理
- 动态卷积:自适应调整卷积参数,显著提升模型表达能力
- 基于Java实现(APP)智能停车场管理系统【100010044】
- RTC领域首个AI算法大赛 AI in RTC 2019 创新挑战圆满落幕
- WPF 自定义分页控件TextBox分页页数只输入数字验证
- 在我们人生的大道上,肯定会遇到许许多多的困难。但我们是不是都知道,在前进的道路上,搬开别人脚下的绊脚石,有时恰恰是为自己铺路?