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

正解:分治$FFT$。

比较简单的一个题。

构造$a,b$的生成函数,$a[i]$表示$a$序列中$i$出现的次数。

考虑分治,我们每次把区间分成两半时,跑两次$FFT$。

对于第一种情况,我们直接把$a$的$[l,mid]$部分和$b$的$[mid+1,r]$卷积即可。

对于第二种情况,我们考虑把$b$序列的$[l,mid]$部分翻转,那么就是$a$的$[mid+1,r]$部分和翻转以后的$b$的$[l,mid]$部分卷积得到的多项式。

然后我们递归两个子区间就行了。

还有两个序列中元素相等的情况,直接特判就行了。

 #include <bits/stdc++.h>
#define il inline
#define RG register
#define ll long long
#define N (500010) using namespace std; struct data{ double x,y; }A[N],B[N]; const double pi=acos(-1.0);
int a[N],b[N],rev[N],n,m,q,Mx,len1,len2;
ll ans[N]; il int gi(){
RG int x=,q=; RG char ch=getchar();
while ((ch<'' || ch>'') && ch!='-') ch=getchar();
if (ch=='-') q=-,ch=getchar();
while (ch>='' && ch<='') x=x*+ch-,ch=getchar();
return q*x;
} il data operator + (const data &a,const data &b){
return (data){a.x+b.x,a.y+b.y};
} il data operator - (const data &a,const data &b){
return (data){a.x-b.x,a.y-b.y};
} il data operator * (const data &a,const data &b){
return (data){a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x};
} il void fft(data *a,RG int n,RG int f){
for (RG int i=;i<n;++i) if (i<rev[i]) swap(a[i],a[rev[i]]);
for (RG int i=;i<n;i<<=){
RG data wn=(data){cos(pi/i),sin(pi/i)},x,y;
for (RG int j=;j<n;j+=i<<){
RG data w=(data){,};
for (RG int k=;k<i;++k,w=w*wn){
x=a[j+k],y=w*a[j+k+i];
a[j+k]=x+y,a[j+k+i]=x-y;
}
}
}
if (f==) return; reverse(a+,a+n);
for (RG int i=;i<n;++i) a[i].x/=n; return;
} il void solve(RG int l,RG int r){
if (l==r) return; RG int mid=(l+r)>>,len,lg=;
for (len=;len<=r-l+;len<<=) ++lg;
for (RG int i=;i<len;++i) rev[i]=rev[i>>]>>|((i&)<<(lg-));
for (RG int i=;i<len;++i) A[i]=B[i]=(data){,};
for (RG int i=l;i<=mid;++i) A[i-l].x=a[i]; fft(A,len,);
for (RG int i=mid+;i<=r;++i) B[i-mid-].x=b[i]; fft(B,len,);
for (RG int i=;i<len;++i) A[i]=A[i]*B[i]; fft(A,len,-);
for (RG int i=;i<len;++i) ans[i+mid++l]+=(ll)(A[i].x+0.5);
for (RG int i=;i<len;++i) A[i]=B[i]=(data){,};
for (RG int i=mid+;i<=r;++i) A[i-mid-].x=a[i]; fft(A,len,);
for (RG int i=l;i<=mid;++i) B[mid-i].x=b[i]; fft(B,len,);
for (RG int i=;i<len;++i) A[i]=A[i]*B[i]; fft(A,len,-);
for (RG int i=;i<len;++i) ans[i+]+=(ll)(A[i].x+0.5);
solve(l,mid),solve(mid+,r); return;
} il void work(){
n=gi(),m=gi(),q=gi(),memset(ans,,sizeof(ans));
memset(a,,sizeof(a)),memset(b,,sizeof(b)),len1=len2=;
for (RG int i=,x;i<=n;++i) ++a[x=gi()],len1=max(len1,x);
for (RG int i=,x;i<=m;++i) ++b[x=gi()],len2=max(len2,x);
for (RG int i=;i<=len1 && i<=len2;++i) ans[]+=1LL*a[i]*b[i];
Mx=max(len1,len2),solve(,Mx);
for (RG int i=;i<=q;++i) printf("%lld\n",ans[gi()]); return;
} int main(){
#ifndef ONLINE_JUDGE
freopen("calc.in","r",stdin);
freopen("calc.out","w",stdout);
#endif
RG int T=gi();
while (T--) work();
return ;
}

bzoj4836 [Lydsy2017年4月月赛]二元运算的更多相关文章

  1. bzoj 4836: [Lydsy2017年4月月赛]二元运算 -- 分治+FFT

    4836: [Lydsy2017年4月月赛]二元运算 Time Limit: 8 Sec  Memory Limit: 128 MB Description 定义二元运算 opt 满足   现在给定一 ...

  2. 【bzoj4836】[Lydsy2017年4月月赛]二元运算 分治+FFT

    题目描述 定义二元运算 opt 满足   现在给定一个长为 n 的数列 a 和一个长为 m 的数列 b ,接下来有 q 次询问.每次询问给定一个数字 c  你需要求出有多少对 (i, j) 使得 a_ ...

  3. [补档][Lydsy2017年4月月赛]抵制克苏恩

    [Lydsy2017年4月月赛]抵制克苏恩 题目 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平. 如果你不玩炉石传说,不必担心,小Q同学会告诉你所有相关的细节.炉石传说是这样的一 ...

  4. 【BZOJ 4832 】 4832: [Lydsy2017年4月月赛]抵制克苏恩 (期望DP)

    4832: [Lydsy2017年4月月赛]抵制克苏恩 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 275  Solved: 87 Descripti ...

  5. 【BZOJ4832】[Lydsy2017年4月月赛]抵制克苏恩 概率与期望

    [BZOJ4832][Lydsy2017年4月月赛]抵制克苏恩 Description 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平.如果你不玩炉石传说,不必担心,小Q同学会告诉 ...

  6. 【BZOJ4883】[Lydsy2017年5月月赛]棋盘上的守卫 KM算法

    [BZOJ4883][Lydsy2017年5月月赛]棋盘上的守卫 Description 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列 必须 ...

  7. BZOJ 4881: [Lydsy2017年5月月赛]线段游戏

    4881: [Lydsy2017年5月月赛]线段游戏 Time Limit: 3 Sec  Memory Limit: 256 MBSubmit: 164  Solved: 81[Submit][St ...

  8. [Bzoj4832][Lydsy2017年4月月赛]抵制克苏恩 (期望dp)

    4832: [Lydsy2017年4月月赛]抵制克苏恩 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 673  Solved: 261[Submit][ ...

  9. 抵制克苏恩[Lydsy2017年4月月赛]

    题目描述 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平.如果你不玩炉石传说,不必担心,小Q同学会告诉你所有相关的细节.炉石传说是这样的一个游戏,每个玩家拥有一个 30 点血量的英 ...

随机推荐

  1. 简单的Web日志分析脚本

    前言 长话短说,事情的起因是这样的,由于工作原因需要分析网站日志,服务器是windows,iis日志,在网上找了找,github找了找,居然没找到,看来只有自己动手丰衣足食. 那么分析方法我大致可分为 ...

  2. linux安装php7

    之前一直对linux研究的比较少,终于下定决心好好把linux玩一下 首先~我是安装了vm虚拟机,然后使用的是centos7的版本.因为vm不好复制粘贴,故使用了xshell连接了我的linux进行操 ...

  3. python3 rjust()函数笔记

    #rjust(12,'l')"12是字符串的长度,l是当字符串不够长的时候,用l填充.并且字符串右对齐".返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串.如果 ...

  4. Photoshop入门教程(五):滤镜

    学习心得:滤镜通常用于摄影行业,是安装在相机镜头前用于过滤自然光的附加镜头,从而获得一些特殊的效果.同理,Photoshop的滤镜也是为了产生特殊的效果.Photoshop滤镜分为两类:一种是内部滤镜 ...

  5. 基于spring boot 和MDC实现 同一笔记录的日志跟踪实现--1.filter

    同一个项目中,一般包含controller/servlet.service.dao等.1笔记录的日志贯穿于controller.service.dao中,在并发情况下,那如何找出该笔日志? 可通过以下 ...

  6. SQL SEVER 数据库日志(Log)文件增长过快的处理

    SQL SERVER 2016数据库,50GB+的数据.有大量的增删和插入操作,数据库log文件变得异常的大,而且增长速度特别的快.周五log文件20GB,周一上班就成了200+GB了 因为数据库恢复 ...

  7. pageX,clientX,offsetX,screenX,offsetLeft,style.left,offsetWidth,scrollWidth的区别以及使用详解

    https://www.cnblogs.com/echolun/p/9231760.html

  8. 使用Koa.js,离不开这十个中间件

    随着ES6的普及,async/await的语法受到更多JS开发者的青睐,Koa.js作为比较早支持使用该语法的Node框架越来越受到大家的喜爱,虽然Koa.js本身支持的功能很有限,但官方和社区提供了 ...

  9. Git简单上传和下载

    本文参考 git-简易指南 编写 上传本地代码到gitHub仓库 第一步:建立git仓库 cd到你的本地项目根目录下,执行git命令 git init 第二步:将项目的所有文件添加到仓库中 git a ...

  10. sql 中单引号内嵌套单引号该怎么解决

    # 在mybatis 中写过一个比较少见的sql, 单引号呢需要嵌套一个单引号,使用双引号就会报错,怎么解决呢: * 这个时候可以使用两个单引号,eg : select id from pgr_dij ...