[Lydsy1704月赛]二元运算

Time Limit: 8 Sec  Memory Limit: 128 MB
Submit: 577  Solved: 201
[Submit][Status][Discuss]

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

HINT

 

这道题就是分治fft的生成函数题,加法应该很好办,但是减法怎么办,就是将其变成加法就可以了。

减法的时候,对于x-y,变成x-mid-1,mid-y,这样就相加就变成了x-y-1,最后把1加上去就可以了。

 #include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<iostream> #define pi acos(-1)
#define ll long long
#define N 100007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-;ch=getchar();}
while(isdigit(ch)){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} int n,m,q,mx;
int a[N],b[N],rev[N<<];
ll ans[N];
struct comp
{
double r,v;
comp(){r=v=0.0;}
comp(double x,double y){r=x,v=y;}
void init(){r=v=0.0;}
friend inline comp operator+(comp x,comp y){return comp(x.r+y.r,x.v+y.v);}
friend inline comp operator-(comp x,comp y){return comp(x.r-y.r,x.v-y.v);}
friend inline comp operator*(comp x,comp y){return comp(x.r*y.r-x.v*y.v,x.r*y.v+x.v*y.r);}
friend inline comp operator/(comp x,int y){return comp(x.r/y,x.v/y);}
}c[N<<],d[N<<]; void FFT(comp *a,int flag,int num)
{
for (int i=;i<num;i++)
if (i<rev[i]) swap(a[i],a[rev[i]]);
for (int i=;i<num;i<<=)
{
comp wn=comp(cos(pi/i),flag*sin(pi/i));
for (int j=;j<num;j+=(i<<))
{
comp w=comp(,);
for (int k=;k<i;k++,w=w*wn)
{
comp x=a[j+k],y=w*a[i+j+k];
a[j+k]=x+y,a[j+k+i]=x-y;
}
}
}
if (flag==-) for (int i=;i<num;i++) a[i].r=a[i].r/num;
}
void CDQ(int l,int r)
{
if (l==r)
{
ans[]+=(ll)a[l]*b[l];
return;
}
int mid=(l+r)>>,num,up=r-l+,L=;
for (num=;num<=up;num<<=,L++);if (L) L--;
for (int i=;i<num;i++) rev[i]=(rev[i>>]>>)|((i&)<<L); memset(c,,sizeof(c[])*num),memset(d,,sizeof(d[])*num);
for (int i=l;i<=mid;i++) c[i-l].r=a[i];
for (int i=mid+;i<=r;i++) d[i-mid-].r=b[i];
FFT(c,,num),FFT(d,,num);
for (int i=;i<num;i++) c[i]=c[i]*d[i];
FFT(c,-,num);
for (int i=;i<num;i++) ans[i+l+mid+]+=(ll)(c[i].r+0.5); memset(c,,sizeof(c[])*num),memset(d,,sizeof(d[])*num);
for (int i=mid+;i<=r;i++) c[i-mid-].r=a[i];
for (int i=l;i<=mid;i++) d[mid-i].r=b[i];
FFT(c,,num),FFT(d,,num);
for (int i=;i<num;i++) c[i]=c[i]*d[i];
FFT(c,-,num);
for (int i=;i<num;i++) ans[i+]+=(ll)(c[i].r+0.5); CDQ(l,mid),CDQ(mid+,r);
}
int main()
{
int T=read();
while(T--)
{
n=read(),m=read(),q=read();
memset(a,,sizeof(a)),memset(b,,sizeof(b)),memset(ans,,sizeof(ans));
for (int i=;i<=n;i++)
{
int x=read();
a[x]++,mx=max(mx,x);
}
for (int i=;i<=m;i++)
{
int x=read();
b[x]++,mx=max(mx,x);
}
CDQ(,mx);
for (int i=;i<=q;i++)
printf("%lld\n",ans[read()]);
}
}
 

#include<cstring>#include<cmath>#include<algorithm>#include<iostream>#include<cstdio>
#define pi acos(-1)#define N 600007using namespace std;inline int read(){int x=0,f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
int R,C,H,W,num,L;int rev[N],a[507][507],b[507][507];struct comp{double r,v;comp(){r=v=0.0;}comp(double x,double y){r=x,v=y;}void init(){r=v=0.0;}friend inline comp operator+(comp x,comp y){return comp(x.r+y.r,x.v+y.v);}friend inline comp operator-(comp x,comp y){return comp(x.r-y.r,x.v-y.v);}friend inline comp operator*(comp x,comp y){return comp(x.r*y.r-x.v*y.v,x.r*y.v+x.v*y.r);}friend inline comp operator/(comp x,int y){return comp(x.r/y,x.v/y);}}a1[N],b1[N],a2[N],b2[N],c[N];char ch[507],T[507][507];
void FFT(comp *a,int flag){for (int i=0;i<num;i++)if (i<rev[i]) swap(a[i],a[rev[i]]);for (int i=1;i<num;i<<=1){comp wn=comp(cos(pi/i),flag*sin(pi/i));for (int j=0;j<num;j+=(i<<1)){comp w=comp(1,0);for (int k=0;k<i;k++,w=w*wn){comp x=a[j+k],y=w*a[j+k+i];a[j+k]=x+y,a[j+k+i]=x-y;}}}if (flag==-1) for (int i=0;i<num;i++) a[i].r=a[i].r/num;}int main(){R=read(),C=read();for (int i=0;i<R;i++){scanf("%s",ch);for (int j=0;j<C;j++){if (ch[j]=='G') a1[i*C+j]=comp(1,0);else b1[i*C+j]=comp(1,0);}}for (num=1;num<=R*C*2;num<<=1,L++);if (L) L--;for (int i=0;i<num;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<L);FFT(a1,1),FFT(b1,1);int Total=read();for (int Case=1;Case<=Total;Case++){H=read(),W=read(),memset(a,0,sizeof(a)),memset(b,0,sizeof(b));for (int i=0;i<num;i++)a2[i].init(),b2[i].init();for (int i=0;i<H;i++)scanf("%s",T[i]);for (int i=0;i<H;i++)for (int j=0;j<W;j++)if (T[i][j]=='G') a2[R*C-1-i*C-j]=comp(1,0);else b2[R*C-1-i*C-j]=comp(1,0);FFT(a2,1),FFT(b2,1);for (int i=0;i<num;i++)a2[i]=a1[i]*a2[i],b2[i]=b1[i]*b2[i];FFT(a2,-1),FFT(b2,-1);for (int i=0;i<R-H;i++)for (int j=0;j<C-W;j++)a[i][j]=(int)(a2[i*C+j+R*C-1].r+0.5),b[i][j]=(int)(b2[i*C+j+R*C-1].r+0.5);int x,y;x=y=0;for (int i=0;i<R-H;i++)for (int j=0;j<=C-W;j++)if (a[i][j]+b[i][j]>a[x][y]+b[x][y]) x=i,y=j;printf("Case #%d: %d %d %d %d\n",Case,x+1,y+1,a[x][y],b[x][y]);}}

bzoj 4836 [Lydsy1704月赛]二元运算 分治FFT+生成函数的更多相关文章

  1. BZOJ 4836: [Lydsy1704月赛]二元运算 分治FFT

    Code: #include<bits/stdc++.h> #define ll long long #define maxn 500000 #define setIO(s) freope ...

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

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

  3. BZOJ4836 [Lydsy1704月赛]二元运算 分治 多项式 FFT

    原文链接http://www.cnblogs.com/zhouzhendong/p/8830036.html 题目传送门 - BZOJ4836 题意 定义二元运算$opt$满足 $$x\ opt\ y ...

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

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

  5. [BZOJ4836]二元运算(分治FFT)

    4836: [Lydsy1704月赛]二元运算 Time Limit: 8 Sec  Memory Limit: 128 MBSubmit: 578  Solved: 202[Submit][Stat ...

  6. BZOJ4836: [Lydsy1704月赛]二元运算

    BZOJ4836: [Lydsy1704月赛]二元运算 https://lydsy.com/JudgeOnline/problem.php?id=4836 分析: 分开做,维护两个桶. 分治每次求\( ...

  7. BZOJ4836: [Lydsy1704月赛]二元运算【分治FFT】【卡常(没卡过)】

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

  8. BZOJ 4555: [Tjoi2016&Heoi2016]求和 [分治FFT 组合计数 | 多项式求逆]

    4555: [Tjoi2016&Heoi2016]求和 题意:求\[ \sum_{i=0}^n \sum_{j=0}^i S(i,j)\cdot 2^j\cdot j! \\ S是第二类斯特林 ...

  9. 【2019北京集训测试赛(七)】 操作 分治+FFT+生成函数

    题目大意:你有$n$个操作和一个初始为$0$的变量$x$. 第$i$个操作为:以$P_i$的概率给$x$加上$A_i$,剩下$1-P_i$的概率给$x$乘上$B_i$. 你袭击生成了一个长度为$n$的 ...

随机推荐

  1. 【Hadoop】配置环境-伪分布式

    目录 1.Linux设置静态IP地址 2.修改主机名和映射文件 3.SSH免密码配置 4.Linux系统JDK的安装和配置 5.Hadoop伪分布式配置和测试 1.Linux设置静态IP地址 1.在L ...

  2. 006---hashlib模块

    hashlib模块 HASH 一般翻译成散列,也可以叫哈希. 把任意长度的输入通过散列算法变换成固定的长度. 该转换是一种压缩映射 MD5 输入任意长度的信息,经过处理.输出为128位的信息(数字指纹 ...

  3. maven 添加自己下载的jar包到本地仓库

    1.在pom文件中添加依赖,其中groupId等变量都自拟. 例如: 2.在命令行执行以下命令,提示build success即表示安装成功. mvn install:install-file -Dg ...

  4. Shoot the Bullet(ZOJ3229)(有源汇上下界最大流)

    描述 ensokyo is a world which exists quietly beside ours, separated by a mystical border. It is a utop ...

  5. (长期更新)OI常用模板

    代码很简单的模板就不收录了. DFT 离散傅立叶变换 void dft(pdd *a,int l,bool r){ int i,j=l/2,k; for(i=1;i<l;++i){ if(i&l ...

  6. ULINE(插入水平线)

    WRITE 'This is Underlined'. ULINE. 输出结果: This is Underlined. ———————————————————

  7. xpath简单入门

    语法: 选取节点: 实例: (贴图转载自w3school) 补充: /a/@href        #获取a标签的href属性 当<div class="demo">& ...

  8. python2.7入门---file(文件)&OS 文件&目录方法

        首先file 对象使用 open 函数来创建,下表列出了 file 对象常用的函数: 序号 方法及描述 1 file.close() 关闭文件.关闭后文件不能再进行读写操作. 2 file.f ...

  9. LeetCode:17. Letter Combinations of a Phone Number(Medium)

    1. 原题链接 https://leetcode.com/problems/letter-combinations-of-a-phone-number/description/ 2. 题目要求 给定一 ...

  10. Leetcode 简略题解 - 共567题

    Leetcode 简略题解 - 共567题     写在开头:我作为一个老实人,一向非常反感骗赞.收智商税两种行为.前几天看到不止两三位用户说自己辛苦写了干货,结果收藏数是点赞数的三倍有余,感觉自己的 ...