【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 ...
随机推荐
- codeforces 600A Extract Numbers
模拟题,意思是一个字符串,单词直接用','或';'来分割,可以为空,把不含前导0的整数和其他单词分别放入A和B.按照一定格式输出. 没有用stl的习惯.维护两个下标i,j,表示开区间(i,j),两段补 ...
- POJ - 3111 K Best(二分)
包含一些ai和bi的集用S来表示,x = max(sigma(ai)/sigma(bi),i 属于S) ,k 表示S的大小,k= |S|. x和k之间具有单调性.k0 < k1 → x0 ≥ x ...
- ELF文件的格式和加载过程
http://blog.csdn.net/lingfong_cool/article/details/7832896 (一) ELF 文件的格式 ELF 文件类型 (1) 可重定位文件( ...
- [转] 防止js全局变量污染方法总结
javaScript 可以随意定义保存所有应用资源的全局变量.但全局变量可以削弱程序灵活性,增大了模块之间的耦合性.在多人协作时,如果定义过多的全局变量 有可能造成全局变量冲突,也就是全局变量污染问题 ...
- oracle用户创建及权限设置(转)
权限: create session create table unlimited tablespace connect resource dba 例: #sqlplus /nolog SQL> ...
- 问题004:如何在windows中打开命令行,有几种方法?
第一种方法:按快捷键 Win+R (run),然后运行框中输入cmd. 第二种方法:开始菜单-->运行-->然后运行框中输入cmd. 第三种方法:在附件当中,找命令行选项即可.
- 牛客小白月赛5 I 区间 (interval) 【前缀和】
链接:https://www.nowcoder.com/acm/contest/135/I 题目描述 Apojacsleam喜欢数组. 他现在有一个n个元素的数组a,而他要对a[L]-a[R]进行M次 ...
- 认识mysql(4)
今日是MySQL的第四篇,难度会稍微加大,加油! 开始吧! 1.外键(foreign key) 1.定义:让当前表字段的值在另一个表的范围内选择 2.语法: foreign key(参考字段名) r ...
- JZOJ 3388. 【NOIP2013模拟】绿豆蛙的归宿
3388. [NOIP2013模拟]绿豆蛙的归宿 (Standard IO) Time Limits: 1000 ms Memory Limits: 131072 KB Detailed Limi ...
- bootstrap-图片样式记录
//三种形状<img src=”img/pic.png” alt=”图片” class=”img-rounded” /><img src=”img/pic.png” alt=”图片” ...