题意:给你一个长度为N(N<=100000)的数列,Q(Q<=200000)次询问,每次给出一个K,问数列中有多少个二元组它们的和小于K
思路:显然不会做嘛,一个比较直接的想法是怎么把所有数两两相加的结果都预处理出来然后弄个前缀就OK啦?然而普通的预处理所有两个数和是要n^2的,这个时候就可以用FFT来加速啦。。
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
const double eps(1e-8);
typedef long long lint;const double PI = acos(-1.0);struct Complex
{double real, image;Complex(double _real, double _image){real = _real;image = _image;}Complex(){}
};Complex operator + (const Complex &c1, const Complex &c2)
{return Complex(c1.real + c2.real, c1.image + c2.image);
}Complex operator - (const Complex &c1, const Complex &c2)
{return Complex(c1.real - c2.real, c1.image - c2.image);
}Complex operator * (const Complex &c1, const Complex &c2)
{return Complex(c1.real*c2.real - c1.image*c2.image, c1.real*c2.image + c1.image*c2.real);
}int rev(int id, int len)
{int ret = 0;for(int i = 0; (1 << i) < len; i++){ret <<= 1;if(id & (1 << i)) ret |= 1;}return ret;
}Complex tA[305000];
void FFT(Complex* a, int len, int DFT)
{for(int i = 0; i < len; i++)tA[rev(i, len)] = a[i];for(int s = 1; (1 << s) <= len; s++){int m = (1 << s);Complex wm = Complex(cos(DFT*2*PI/m), sin(DFT*2*PI/m));for(int k = 0; k < len; k += m){Complex w = Complex(1, 0);for(int j = 0; j < (m >> 1); j++){Complex u = w*tA[k + j + (m >> 1)];Complex t = tA[k + j];tA[k + j] = t + u;tA[k + j + (m >> 1)] = t - u;w = w*wm;}}}if(DFT == -1) for(int i = 0; i < len; i++) tA[i].real /= len, tA[i].image /= len;for(int i = 0; i < len; i++) a[i] = tA[i];return;
}int branch[100010];
int num[300010];
Complex a[305000];//(1 << 17 = 131072, 1 << 18 = 262144)
lint A[200010];
lint sumA[305010];//表示A[i]的前缀和int main()
{int T, n;scanf("%d", &T);while(T--){int q;scanf("%d%d", &n,&q);int maxBranch = 0;for(int i = 0; i < n; i++){scanf("%d", branch + i);maxBranch = max(maxBranch, branch[i]);}memset(num, 0, sizeof(num));for(int i = 0; i < n; i++)num[branch[i]]++;for(int i = 0; i <= maxBranch; i++)a[i] = Complex(num[i], 0);int len = 1;while(len <= maxBranch) len <<= 1;len <<= 1;for(int i = maxBranch + 1; i < len; i++)a[i] = Complex(0, 0);FFT(a, len, 1);for(int i = 0; i < len; i++)a[i] = a[i]*a[i];FFT(a, len, -1);for(int i = 0; i <= 2*maxBranch; i++)A[i] = (lint)(a[i].real + 0.5);for(int i = 0; i <= 2*maxBranch; i += 2)A[i] -= num[i >> 1];for(int i = 0; i <= 2*maxBranch; i++)A[i] /= 2;//到现在为止A[i]表示的是去两根不同的branch的长度和为i的组合种数sumA[0] = 0;for(int i = 1; i <= 2*maxBranch; i++)sumA[i] = sumA[i - 1] + A[i];while(q--){int k;scanf("%d",&k);printf("%lld\n",sumA[k-1]);}/*     lint ans = 0;sort(branch, branch + n);for(int i = 1; i <= n; i++)//以第i根作为边最长的{lint tmp = sumA[2*maxBranch] - sumA[branch[i]];//另外两条边长度和要大于branch[i]tmp -= (lint)(n - i)*(i - 1);//另外两条一条比branch[i]长, 一条不比它长tmp -= (lint)(n - i)*(n - i - 1) / 2;//两条都比他长tmp -= n - 1;//另外两条的组合中包括它自己的组合ans += tmp;}double p = ans*6./n/(n - 1)/(n - 2);printf("%.7f\n", p);*/}return 0;
}

哈理工大学ACM程序设计全国邀请赛D D Pairs(FFT)相关推荐

  1. 2019 ACM - ICPC 全国邀请赛(南昌) 题解(9 / 12)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 The 2019 ICPC China Nanchang National Invitation ...

  2. 2019 ACM - ICPC 全国邀请赛(西安)题解(9 / 13)

    The 2019 ACM-ICPC China Shannxi Provincial Programming Contest 目录 The 2019 ACM-ICPC China Shannxi Pr ...

  3. 2019 ACM/ICPC 全国邀请赛(西安)J And And And (树DP+贡献计算)

    Then n - 1n−1 lines follow. ii-th line contains two integers f_{a_i}(1 \le f_{a_i} < i)fai​​(1≤fa ...

  4. 2019 ACM - ICPC 西安邀请赛 B. Product (杜教筛) 简单数论(bushi)

    G.(2019 ACM/ICPC 全国邀请赛(西安)B) Product Weblink https://nanti.jisuanke.com/t/39269 Problem && S ...

  5. 2020 年 “联想杯”全国高校程序设计在线邀请赛暨第三届上海理工大学程序设计竞赛题解

    2020 年 "联想杯"全国高校程序设计在线邀请赛暨第三届上海理工大学程序设计竞赛题解 萌新又来写题解啦 原题链接 (不是按照题号顺序来的QWQ) L. Lottery Ticke ...

  6. 2021 ICPC全国邀请赛(西安)太原理工大学收获3枚奖牌

    2021 ICPC 国际大学生程序设计竞赛全国邀请赛,于2021年6月5-6日在西安西北工业大学举行. 这次比赛,太原理工大学共派出3个队伍参加比赛,获得2枚银牌1枚铜牌. 通过这个比赛,锻炼了队伍, ...

  7. “师创杯”山东理工大学第九届ACM程序设计竞赛 正式赛 F.校赛~校赛~【思维+规律题】

    校赛~校赛~ Time Limit: 1000MS  Memory Limit: 65536KB Submit  Statistic Problem Description SDUT 的校赛是从 20 ...

  8. 哈尔滨理工大学第五届ACM程序设计竞赛(热身)

    Link:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2234 土豪银行 Time ...

  9. 2020 年 “联想杯”全国高校程序设计在线邀请赛H. Hay Mower

    2020 年 "联想杯"全国高校程序设计在线邀请赛H. Hay Mower 题意:n × m 网格图,每个格子内的草每秒增加 ai,j,接下 来 k 个操作,每个操作会在某个时间把 ...

最新文章

  1. oracle 跑旧的文件,移动datafile以后,旧的datafile是否还被Oracle使用
  2. C语言中连续调用rand函数,返回值不变
  3. 最大矩形面积_JAVA
  4. 六大设计原则之迪米特法则
  5. 21行代码AC_标题 Excel地址 2017年蓝桥杯真题(解题报告+通法)
  6. centos7 + VMware Workstation Pro
  7. STL库中string类内存布局的探究
  8. 如何在本地数据中心安装Service Fabric for Windows集群
  9. 狗窝里的小日子- 3 ...
  10. Cannot find module 'less-bundle-promise'
  11. pandas中的数据如何转化为张量?
  12. hive中的日期转换函数
  13. React-Native入门(2)-简单阐述跳转
  14. shell脚本:判断本地和远程文件是否存在
  15. hihocoder#1513 : 小Hi的烦恼
  16. 错误C2398:从“double”转换为“float”需要缩小转换
  17. centos 安装图形桌面
  18. 昱君金融超市西祠版开通了
  19. 21天学通C语言-学习笔记(6)
  20. linux查找文件夹名称

热门文章

  1. MPEG-2 最后一个美国专利已于2018 年 2月过期
  2. 项目复盘的12条秘诀
  3. windows添加系统变量
  4. 积分里的Cauchy-Bunyakovsky不等式
  5. 2022081班李亚楠20220919
  6. 谐振子的动力学学运动
  7. [nexus]基于nexus搭建npm仓库及上传插件到仓库
  8. 进口商贸易融资工具:提货担保和提单背书
  9. mysql从小到大的语句_MySQL 我自己常用的语句汇总
  10. Android开发完全讲义(第三版)已出版