【bzoj4836】二元运算 分治FFT
Description
定义二元运算 opt 满足
现在给定一个长为 n 的数列 a 和一个长为 m 的数列 b ,接下来有 q 次询问。每次询问给定一个数字 c
你需要求出有多少对 (i, j) 使得 a_i opt b_j=c 。
Input
第一行是一个整数 T (1≤T≤10) ,表示测试数据的组数。
对于每组测试数据:
第一行是三个整数 n,m,q (1≤n,m,q≤50000) 。
第二行是 n 个整数,表示 a_1,a_2,?,a_n (0≤a_1,a_2,?,a_n≤50000) 。
第三行是 m 个整数,表示 b_1,b_2,?,b_m (0≤b_1,b_2,?,b_m≤50000) 。
第四行是 q 个整数,第 i 个整数 c_i (0≤c_i≤100000) 表示第 i 次查询的数。
Output
对于每次查询,输出一行,包含一个整数,表示满足条件的 (i, j) 对的个数。
Sample Input
2
2 1 5
1 3
2
1 2 3 4 5
2 2 5
1 3
2 4
1 2 3 4 5
Sample Output
1
0
1
0
0
1
0
1
0
1
Sol
首先一眼看上去有点像FFT,但是由于值域的限制我们不能直接做,考虑按权值分治,每次把A中小于mid的和B中大于mid的进行FFT,统计答案的时候记得加上l和mid+1,再把B反转,然后把A中大于mid的和B中小于mid的进行FFT,统计答案的时候记得右移一位。
细节:分治的时候len和memset的范围一定要按照当前区间长度来,否则T飞。
Code
#include <bits/stdc++.h>
#define pi acos(-1.0)
using namespace std;
int A[50005],B[50005],T,mx,x,n,m,q,len,i,j,k;long long ans[100005];
struct cp
{
	double x,y;
	cp(double x=0.0,double y=0.0):x(x),y(y){}
	friend cp operator+(cp a,cp b){return cp(a.x+b.x,a.y+b.y);}
	friend cp operator-(cp a,cp b){return cp(a.x-b.x,a.y-b.y);}
	friend cp operator*(cp a,cp b){return cp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
}C[131073],D[131073],w,wn,t;
void fft(cp *a,int n,int op)
{
	for(i=k=0;i<n;i++){if(i>k) swap(a[i],a[k]);for(j=(n>>1);(k^=j)<j;j>>=1);}
	for(k=2,wn=cp(cos(2*pi*op/k),sin(2*pi*op/k));k<=n;k<<=1,wn=cp(cos(2*pi*op/k),sin(2*pi*op/k)))
		for(i=0,w=cp(1,0);i<n;i+=k,w=cp(1,0)) for(j=0;j<(k>>1);j++,w=w*wn)
			t=a[i+j+(k>>1)]*w,a[i+j+(k>>1)]=a[i+j]-t,a[i+j]=a[i+j]+t;
	if(op==-1) for(int i=0;i<n;i++) a[i].x/=n;
}
void solve(int l,int r)
{
	if(l==r){ans[0]+=1ll*A[l]*B[l];return;}
	int mid=(l+r)>>1;for(len=1;len<r-l+1;len<<=1);
	memset(C,0,sizeof(cp)*len);memset(D,0,sizeof(cp)*len);
	for(int i=l;i<=mid;i++) C[i-l].x=A[i];
	for(int i=mid+1;i<=r;i++) D[i-mid-1].x=B[i];
	fft(C,len,1);fft(D,len,1);
	for(int i=0;i<len;i++) C[i]=C[i]*D[i];fft(C,len,-1);
	for(int i=0;i<len;i++) ans[i+l+mid+1]+=1ll*(C[i].x+0.1);
	memset(C,0,sizeof(cp)*len);memset(D,0,sizeof(cp)*len);
	for(int i=mid+1;i<=r;i++) C[i-mid-1].x=A[i];
	for(int i=l;i<=mid;i++) D[mid-i].x=B[i];
	fft(C,len,1);fft(D,len,1);
	for(int i=0;i<len;i++) C[i]=C[i]*D[i];fft(C,len,-1);
	for(int i=0;i<len;i++) ans[i+1]+=1ll*(C[i].x+0.1);
	solve(l,mid);solve(mid+1,r);
}
int main()
{
	for(scanf("%d",&T);T--;)
	{
		memset(A,0,sizeof(A));memset(B,0,sizeof(B));memset(ans,0,sizeof(ans));
		scanf("%d%d%d",&n,&m,&q);mx=0;
		for(int i=1;i<=n;i++) scanf("%d",&x),A[x]++,mx=max(mx,x);
		for(int i=1;i<=m;i++) scanf("%d",&x),B[x]++,mx=max(mx,x);
		for(solve(0,mx);q--;) scanf("%d",&x),printf("%lld\n",ans[x]);
	}
}
【bzoj4836】二元运算 分治FFT的更多相关文章
- [BZOJ4836]二元运算(分治FFT)
		4836: [Lydsy1704月赛]二元运算 Time Limit: 8 Sec Memory Limit: 128 MBSubmit: 578 Solved: 202[Submit][Stat ... 
- 【bzoj4836】[Lydsy2017年4月月赛]二元运算  分治+FFT
		题目描述 定义二元运算 opt 满足 现在给定一个长为 n 的数列 a 和一个长为 m 的数列 b ,接下来有 q 次询问.每次询问给定一个数字 c 你需要求出有多少对 (i, j) 使得 a_ ... 
- bzoj 4836 [Lydsy1704月赛]二元运算 分治FFT+生成函数
		[Lydsy1704月赛]二元运算 Time Limit: 8 Sec Memory Limit: 128 MBSubmit: 577 Solved: 201[Submit][Status][Di ... 
- bzoj 4836: [Lydsy2017年4月月赛]二元运算  -- 分治+FFT
		4836: [Lydsy2017年4月月赛]二元运算 Time Limit: 8 Sec Memory Limit: 128 MB Description 定义二元运算 opt 满足 现在给定一 ... 
- BZOJ 4836: [Lydsy1704月赛]二元运算 分治FFT
		Code: #include<bits/stdc++.h> #define ll long long #define maxn 500000 #define setIO(s) freope ... 
- BZOJ4836 [Lydsy1704月赛]二元运算 分治 多项式 FFT
		原文链接http://www.cnblogs.com/zhouzhendong/p/8830036.html 题目传送门 - BZOJ4836 题意 定义二元运算$opt$满足 $$x\ opt\ y ... 
- BZOJ4836: [Lydsy1704月赛]二元运算【分治FFT】【卡常(没卡过)】
		Description 定义二元运算 opt 满足 现在给定一个长为 n 的数列 a 和一个长为 m 的数列 b ,接下来有 q 次询问.每次询问给定一个数字 c 你需要求出有多少对 (i, j) 使 ... 
- BNUOJ 51279[组队活动 Large](cdq分治+FFT)
		传送门 大意:ACM校队一共有n名队员,从1到n标号,现在n名队员要组成若干支队伍,每支队伍至多有m名队员,求一共有多少种不同的组队方案.两个组队方案被视为不同的,当且仅当存在至少一名队员在两种方案中 ... 
- hdu 5730 Shell Necklace [分治fft | 多项式求逆]
		hdu 5730 Shell Necklace 题意:求递推式\(f_n = \sum_{i=1}^n a_i f_{n-i}\),模313 多么优秀的模板题 可以用分治fft,也可以多项式求逆 分治 ... 
随机推荐
- win7下cygwin 中 root用户的设置
			问题描述: cygwin 在 win10下安装完成后使用当前用户登录后看所在磁盘的文件权限是没有问题的,但在cygwin编译出来的文件的权限为空,这个问题可以使用以下方法来解决: 解决办法: 将cyg ... 
- Python函数的进阶
			一 函数的动态参数 *agrs 位置参数动态传参 *args 接收多个位置参数 def func(*args): print(args) func("女儿国","西 ... 
- linux之sort用法
			sort命令是帮我们依据不同的数据类型进行排序,其语法及常用参数格式: sort [-bcfMnrtk][源文件][-o 输出文件] 补充说明:sort可针对文本文件的内容,以行为单位来排序. 参 数 ... 
- express源码学习
			终于腾出手来学习express.express在node.js中一株独秀.好像任何一种有主导的托管平台的语言,都出现这现象--马太效应.express是社区的共同孩子,里面聚集上社区最好的常用模块.从 ... 
- 【原创】12. MYSQL++之Template Query
			1. 什么是Template Query 在我们实际的编程过程中,我们很容易碰到printf这类需要在运行时来决定到底打印出什么的函数,例如 printf(“hello %s”, sth); 在这个例 ... 
- Python和其他语言的区别 (简单精辟啊 手打)
			首先是简单 读和写非常容易 免费 免费且开源 社区为专业人士和初学者提供知识和经验的分享交流平台 兼容性 与多平台兼容 面向对象 支持面向对象编程 php面向网络 函数库 python 社区创建了丰富 ... 
- 非root配置linux下vim
			在机子目录下建立 .vim文件夹 例如 /home/xxx/.vim 在~文件夹下建立.vimrc文件 这是你自己配置文件 vim虽然启用了格式化高亮.行号显示,以及括号匹配.自动缩进等编辑功能,对于 ... 
- 【转】Provisional headers are shown
			在chrome开发者工具的 Network 面板中,某些请求头后面会跟着下面这行文字: Provisional headers are shown 这种请求实际上根本没有产生,对应的请求头当然也不应该 ... 
- Ubuntu下配置Apache的Worker模式
			其实Apache本身的并发能力是足够强大的,但是Ubuntu默认安装的是Prefork模式下的Apache.所以导致很多人后面盲目的去 安装lighttpd或者nginx一类替代软件.但是这类软件有一 ... 
- ubuntu 环境变量设置
			一:用于当前终端:在当前终端中输入:export PATH=$PATH:<你的要加入的路径>不过上面的方法只适用于当前终端,一旦当前终端关闭或在另一个终端中,则无效.export NDK_ ... 
