【bzoj4836】[Lydsy2017年4月月赛]二元运算 分治+FFT
题目描述
输入
输出
对于每次查询,输出一行,包含一个整数,表示满足条件的 (i, j) 对的个数。
样例输入
2
2 1 5
1 3
2
1 2 3 4 5
2 2 5
1 3
2 4
1 2 3 4 5
样例输出
1
0
1
0
0
1
0
1
0
1
题解
分治+FFT
如果只有第一种运算就是裸的FFT求卷积;只有第二种运算可以把B序列翻转,然后求卷积即可。
但是有x与y大小关系的限制使得我们不能直接求卷积来得出答案。
考虑分治,对于每个区间$[l,r]$,处理出A中的$[l,mid]$与B中的$[mid+1,r]$对答案的贡献以及A中的$[mid+1,r]$与B中的$[l,mid]$对答案的贡献,这两个是有严格的x与y的大小关系的,分别使用FFT求卷积解决。再递归处理子区间即可。
时间复杂度$O(Tn\log^2n)$。一开始len开了正常的2倍导致无限TLE,QAQ
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 140010
#define rint register int
using namespace std;
typedef long long ll;
const double pi = acos(-1);
struct data
{
double x , y;
data() {}
data(double x0 , double y0) {x = x0 , y = y0;}
data operator+(const data &a)const {return data(x + a.x , y + a.y);}
data operator-(const data &a)const {return data(x - a.x , y - a.y);}
data operator*(const data &a)const {return data(x * a.x - y * a.y , x * a.y + y * a.x);}
}ta[N] , tb[N];
ll a[N] , b[N] , c[N];
inline int read()
{
static int ret; static char ch = getchar();
ret = 0;
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9') ret = ret * 10 + ch - '0' , ch = getchar();
return ret;
}
void fft(data *a , int n , int flag)
{
rint i , j , k;
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 ; k <= n ; k <<= 1)
{
data wn(cos(2 * pi * flag / k) , sin(2 * pi * flag / k));
for(i = 0 ; i < n ; i += k)
{
data w(1 , 0) , t;
for(j = i ; j < i + (k >> 1) ; j ++ , w = w * wn)
t = w * a[j + (k >> 1)] , a[j + (k >> 1)] = a[j] - t , a[j] = a[j] + t;
}
}
if(flag == -1) for(i = 0 ; i < n ; i ++ ) a[i].x /= n;
}
void work(ll *a , ll *b , int n , bool flag)
{
rint i;
for(i = 0 ; i < n ; i ++ ) ta[i].x = a[i] , ta[i].y = ta[i + n].x = ta[i + n].y = 0;
for(i = 0 ; i < n ; i ++ ) tb[i].x = (flag ? b[n - 1 - i] : b[i]) , tb[i].y = tb[i + n].x = tb[i + n].y = 0;
fft(ta , n << 1 , 1) , fft(tb , n << 1 , 1);
for(i = 0 ; i < n << 1 ; i ++ ) ta[i] = ta[i] * tb[i];
fft(ta , n << 1 , -1);
}
void solve(int l , int r)
{
if(l == r)
{
c[0] += a[l] * b[l];
return;
}
int mid = (l + r) >> 1 , n = r - l + 1;
rint i;
work(a + l , b + mid + 1 , n >> 1 , 0);
for(i = 0 ; i < n ; i ++ ) c[i + l + mid + 1] += (ll)(ta[i].x + 0.5);
work(a + mid + 1 , b + l , n >> 1 , 1);
for(i = 0 ; i < n ; i ++ ) c[i + 1] += (ll)(ta[i].x + 0.5);
solve(l , mid) , solve(mid + 1 , r);
}
int main()
{
int T;
T = read();
while(T -- )
{
memset(a , 0 , sizeof(a)) , memset(b , 0 , sizeof(b)) , memset(c , 0 , sizeof(c));
int n , m , q , x , k = 0 , len;
rint i;
n = read() , m = read() , q = read();
for(i = 1 ; i <= n ; i ++ ) x = read() , a[x] ++ , k = max(k , x);
for(i = 1 ; i <= m ; i ++ ) x = read() , b[x] ++ , k = max(k , x);
for(len = 1 ; len <= k ; len <<= 1);
solve(0 , len - 1);
while(q -- ) printf("%lld\n" , c[read()]);
}
return 0;
}
【bzoj4836】[Lydsy2017年4月月赛]二元运算 分治+FFT的更多相关文章
- bzoj 4836: [Lydsy2017年4月月赛]二元运算  -- 分治+FFT
		
4836: [Lydsy2017年4月月赛]二元运算 Time Limit: 8 Sec Memory Limit: 128 MB Description 定义二元运算 opt 满足 现在给定一 ...
 - bzoj4836 [Lydsy2017年4月月赛]二元运算
		
Description 定义二元运算 opt 满足 现在给定一个长为 n 的数列 a 和一个长为 m 的数列 b ,接下来有 q 次询问.每次询问给定一个数字 c 你需要求出有多少对 (i, j) ...
 - bzoj 4836 [Lydsy1704月赛]二元运算 分治FFT+生成函数
		
[Lydsy1704月赛]二元运算 Time Limit: 8 Sec Memory Limit: 128 MBSubmit: 577 Solved: 201[Submit][Status][Di ...
 - BZOJ 4836: [Lydsy1704月赛]二元运算 分治FFT
		
Code: #include<bits/stdc++.h> #define ll long long #define maxn 500000 #define setIO(s) freope ...
 - [补档][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 ...
 
随机推荐
- hdu-3549 Flow Problem---最大流模板题(dinic算法模板)
			
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3549 题目大意: 给有向图,求1-n的最大流 解题思路: 直接套模板,注意有重边 传送门:网络流入门 ...
 - find - 递归地在层次目录中处理文件
			
总览 SYNOPSIS find [path...] [expression] 描述 DESCRIPTION 这个文档是GNU版本 find 命令的使用手册. find 搜索目录树上的每一个文件名,它 ...
 - javaweb基础(27)_jsp标签库实例
			
一.开发标签库 1.1.开发防盗链标签 1.编写标签处理器类:RefererTag.java 1 package me.gacl.web.simpletag; 2 3 import java.io.I ...
 - GPU并行编程:内核及函数的实现
			
原文链接 回想一下我们之前在设备上使用“kernelFunction<<<1,1>>>(..)”执行一个函数的代码,我在那里还曾说过后面会细说,本文就详细介绍一下参 ...
 - dn.net/blueheart20/article/details/22080489
			
dn.net/blueheart20/article/details/22080489
 - InstallShield Limited Edition for Visual Studio 2013 图文教程打包安装包
			
http://www.wuleba.com/23892.html 从Visual Studio 2012开始,微软就把自家原来的安装与部署工具彻底废掉了,转而让大家去安装使用第三方的打包工具“Inst ...
 - 通过Jquery获取RadioButtonList选中值
			
推荐 使用第二种,第一种有时候不起作用 第一种:通过find方法 获取RadioButtonList所选中的值 <script type="text/javascript"& ...
 - 51nod——2487小b和环
			
dp[ i ][ 0 ] : 第i个位置不取 dp[ i ][ 1 ] : 第i个位置取 这样就可以得到状态转移方程: dp[i][0]=max(max(dp[i][0],dp[i-1][1]),dp ...
 - MySQL - FULL JOIN
			
SQL FULL JOIN 关键字 只要其中某个表存在匹配,FULL JOIN 关键字就会返回行. FULL JOIN 关键字语法 SELECT column_name(s) FROM table_n ...
 - MySql学习笔记01
			
MySql01 课程介绍 数据库简介 之前通过流操作文件的方式存储数据弊端: 1. 效率低 2. 不管是存还是取都比较麻烦 3. 一般只能存储小量数据 4. 只能存储文本数据 什么是DB DataBa ...