bzoj4836 [Lydsy2017年4月月赛]二元运算
Description
Input
Output
对于每次查询,输出一行,包含一个整数,表示满足条件的 (i, j) 对的个数。
Sample Input
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
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月月赛]二元运算的更多相关文章
- bzoj 4836: [Lydsy2017年4月月赛]二元运算 -- 分治+FFT
4836: [Lydsy2017年4月月赛]二元运算 Time Limit: 8 Sec Memory Limit: 128 MB Description 定义二元运算 opt 满足 现在给定一 ...
- 【bzoj4836】[Lydsy2017年4月月赛]二元运算 分治+FFT
题目描述 定义二元运算 opt 满足 现在给定一个长为 n 的数列 a 和一个长为 m 的数列 b ,接下来有 q 次询问.每次询问给定一个数字 c 你需要求出有多少对 (i, j) 使得 a_ ...
- [补档][Lydsy2017年4月月赛]抵制克苏恩
[Lydsy2017年4月月赛]抵制克苏恩 题目 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平. 如果你不玩炉石传说,不必担心,小Q同学会告诉你所有相关的细节.炉石传说是这样的一 ...
- 【BZOJ 4832 】 4832: [Lydsy2017年4月月赛]抵制克苏恩 (期望DP)
4832: [Lydsy2017年4月月赛]抵制克苏恩 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 275 Solved: 87 Descripti ...
- 【BZOJ4832】[Lydsy2017年4月月赛]抵制克苏恩 概率与期望
[BZOJ4832][Lydsy2017年4月月赛]抵制克苏恩 Description 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平.如果你不玩炉石传说,不必担心,小Q同学会告诉 ...
- 【BZOJ4883】[Lydsy2017年5月月赛]棋盘上的守卫 KM算法
[BZOJ4883][Lydsy2017年5月月赛]棋盘上的守卫 Description 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列 必须 ...
- BZOJ 4881: [Lydsy2017年5月月赛]线段游戏
4881: [Lydsy2017年5月月赛]线段游戏 Time Limit: 3 Sec Memory Limit: 256 MBSubmit: 164 Solved: 81[Submit][St ...
- [Bzoj4832][Lydsy2017年4月月赛]抵制克苏恩 (期望dp)
4832: [Lydsy2017年4月月赛]抵制克苏恩 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 673 Solved: 261[Submit][ ...
- 抵制克苏恩[Lydsy2017年4月月赛]
题目描述 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平.如果你不玩炉石传说,不必担心,小Q同学会告诉你所有相关的细节.炉石传说是这样的一个游戏,每个玩家拥有一个 30 点血量的英 ...
随机推荐
- 回滚revert和reset区别
分享请标明来自: https://www.css3.io/hui-gun.html 背景 git是一个庞大的工具,我们要开始扫盲一些常用的命令.回滚代码在项目中必然会遇到,下面我们介绍在git中如何回 ...
- runlevel:启动运行级别(3-13)
0:halt 关机模式1:single user 单用户2:Multiuser 多用户3:Full multiuser mode 命令行模式4:unused 没有使用5:Xll 桌面模式6:reboo ...
- canvas基础入门(二)绘制线条、三角形、七巧板
复杂的内容都是有简单的线条结合而成的,想要绘制出复杂好看的内容先从画直线开始 canvas绘制直线先认识几个函数 beginPath():开始一条路径,或重置当前的路径 moveTo(x,y):用于规 ...
- #1413 : Rikka with String 后缀自动机 + 二级差分
http://hihocoder.com/problemset/problem/1413?sid=1199641 这题断断续续做了2个多星期吧,一直不会 设总答案为sum,替换后新加的子串数量为x,失 ...
- 【3dsMax安装失败,如何卸载、安装3dMax 2019?】
AUTODESK系列软件着实令人头疼,安装失败之后不能完全卸载!!!(比如maya,cad,3dsmax等).有时手动删除注册表重装之后还是会出现各种问题,每个版本的C++Runtime和.NET f ...
- 转:Android中的Handler的机制与用法详解
注:Message类的用法: message的几个参数都可以携带数据,其中arg1与arg2可以携带int类型,what是用户自定义的int型,这样接受者可以了解这个消息的信息. 说明:使用Messa ...
- 探讨PHP获取checkbox值
如何才能正确的实现PHP获取checkbox值对于初学者来说还是比较陌生的.在这里我们将为大家详细介绍相关的实现方法,希望对大家有所帮助. > > > weeks后的中括号不可漏,否 ...
- GitKraken使用教程-基础部分(1)
1. 首次打开程序 第一次打开GitKraken程序时, GitKraken会提示需要登陆,可以用github.com的账号登陆,或者用邮箱创建账号登陆(如图 1‑1). 图 1‑1登陆帐户界面 登陆 ...
- PHP函数的引用传递(地址传递)
PHP中的引用: 在PHP中,变量名和变量内容是不一样的,因此同样的内容可以有不同的名字.在PHP中引用意味着用不同的名字访问同一个变量的内容. 比如:$a = 'hello world'; $b = ...
- netty之==TCP粘包/拆包问题解决之道(一)
一.TCP粘包/拆包是什么 TCP是一个“流”协议,所谓流,就是没有界限的一长串二进制数据.TCP作为传输层协议并不不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行数据包的划分,所以在 ...