XJTUOJ wmq的A×B Problem FFT/NTT
wmq的A×B Problem
发布时间: 2017年4月9日 17:06 最后更新: 2017年4月9日 17:07 时间限制: 3000ms 内存限制: 512M
这是一个非常简单的问题。
wmq如今开始学习乘法了!他为了训练自己的乘法计算能力,写出了n个整数,并且对每两个数a,b都求出了它们的乘积a×b。现在他想知道,在求出的n(n−1)2个乘积中,除以给定的质数m余数为k(0≤k<m)的有多少个。
第一行为测试数据的组数。
对于每组测试数据,第一行为2个正整数n,m,2≤n,m≤60000,分别表示整数的个数以及除数。
接下来一行有n个整数,满足0≤ai≤109。
保证总输出行数∑m≤3×105。
对每组数据输出m行,其中第i行为除以m余数为(i−1)的有多少个。
2
4 5
2 0 1 7
4 2
2 0 1 6
3
0
2
0
1
6
0
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18+1LL;
const double pi = acos(-1.0);
const int N = +, M = 1e3+,inf = 2e9,mod = ; int MOD;
inline int mul(int a, int b){
return (long long)a * b % MOD;
}
int power(int a, int b){
int ret = ;
for (int t = a; b; b >>= ){
if (b & )ret = mul(ret, t);
t = mul(t, t);
}
return ret;
}
int cal_root(int mod)
{
int factor[], num = , s = mod - ;
MOD = mod--;
for (int i = ; i * i <= s; i++){
if (s % i == ){
factor[num++] = i;
while (s % i == )s /= i;
}
}
if (s != )factor[num++] = s;
for (int i = ;; i++){
int j = ;
for (; j < num && power(i, mod / factor[j]) != ; j++);
if (j == num)return i;
}
}
struct Complex {
long double r , i ;
Complex () {}
Complex ( double r , double i ) : r ( r ) , i ( i ) {}
Complex operator + ( const Complex& t ) const {
return Complex ( r + t.r , i + t.i ) ;
}
Complex operator - ( const Complex& t ) const {
return Complex ( r - t.r , i - t.i ) ;
}
Complex operator * ( const Complex& t ) const {
return Complex ( r * t.r - i * t.i , r * t.i + i * t.r ) ;
}
} ; void FFT ( Complex y[] , int n , int rev ) {
for ( int i = , j , t , k ; i < n ; ++ i ) {
for ( j = , t = i , k = n >> ; k ; k >>= , t >>= ) j = j << | t & ;
if ( i < j ) swap ( y[i] , y[j] ) ;
}
for ( int s = , ds = ; s <= n ; ds = s , s <<= ) {
Complex wn = Complex ( cos ( rev * * pi / s ) , sin ( rev * * pi / s ) ) , w ( , ) , t ;
for ( int k = ; k < ds ; ++ k , w = w * wn ) {
for ( int i = k ; i < n ; i += s ) {
y[i + ds] = y[i] - ( t = w * y[i + ds] ) ;
y[i] = y[i] + t ;
}
}
}
if ( rev == - ) for ( int i = ; i < n ; ++ i ) y[i].r /= n ;
} Complex s[N];
int T,n,m,x,num[N];
LL ans[N],mo[N],fmo[N];
int main() {
scanf("%d",&T);
while(T--) {
scanf("%d%d",&n,&m);
int G = cal_root(m);
for(LL i = , t = ; i < m-; ++i,t = t*G%m)
mo[i] = t,fmo[t] = i;
memset(num,,sizeof(num));
LL cnt0 = ;
for(int i = ; i <= m; ++i) ans[i] = ;
for(int i = ; i <= n; ++i) {
scanf("%d",&x);
x%=m;
if(x == ) cnt0++;
else {
num[fmo[x]]++;
}
}
int n1 = ;
for(n1=;n1<=(*m-);n1<<=);
for(int i = ; i < m; ++i) s[i] = Complex(num[i],);
for(int i = m; i < n1; ++i) s[i] = Complex(,);
FFT(s,n1,);
for(int i = ; i < n1; ++i) s[i] = s[i]*s[i];
FFT(s,n1,-);
printf("%lld\n",(LL)cnt0*(n-cnt0)+(LL)cnt0*(cnt0-)/);
for(int i = ; i <= *m-; ++i) {
LL now = (LL)(s[i].r+0.5);
if(i%==) now -= num[i/];
now/=;
ans[mo[i%(m-)]] += now;
}
for(int i = ; i < m; ++i) printf("%lld\n",ans[i]);
}
return ;
}
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18+1LL;
const double pi = acos(-1.0);
const int N = +, M = 1e3+,inf = 2e9; int MOD;
inline int mul2(int a, int b){
return (long long)a * b % MOD;
}
int power(int a, int b){
int ret = ;
for (int t = a; b; b >>= ){
if (b & )ret = mul2(ret, t);
t = mul2(t, t);
}
return ret;
}
int cal_root(int mod)
{
int factor[], num = , s = mod - ;
MOD = mod--;
for (int i = ; i * i <= s; i++){
if (s % i == ){
factor[num++] = i;
while (s % i == )s /= i;
}
}
if (s != )factor[num++] = s;
for (int i = ;; i++){
int j = ;
for (; j < num && power(i, mod / factor[j]) != ; j++);
if (j == num)return i;
}
} LL P,G;
LL mul(LL x,LL y){
return (x*y-(LL)(x/(long double)P*y+1e-)*P+P)%P;
}
LL qpow(LL x,LL k,LL p){
LL ret=;
while(k){
if(k&) ret=mul(ret,x);
k>>=;
x=mul(x,x);
}
return ret;
}
LL wn[];
void getwn(){
for(int i=; i<=; ++i){
int t=<<i;
wn[i]=qpow(G,(P-)/t,P);
}
}
void NTT_init() {
P = 3221225473LL,G = ;
getwn();
}
int len;
void NTT(LL y[],int op){
for(int i=,j=len>>,k; i<len-; ++i){
if(i<j) swap(y[i],y[j]);
k=len>>;
while(j>=k){
j-=k;
k>>=;
}
if(j<k) j+=k;
}
int id=;
for(int h=; h<=len; h<<=) {
++id;
for(int i=; i<len; i+=h){
LL w=;
for(int j=i; j<i+(h>>); ++j){
LL u=y[j],t=mul(y[j+h/],w);
y[j]=u+t;
if(y[j]>=P) y[j]-=P;
y[j+h/]=u-t+P;
if(y[j+h/]>=P) y[j+h/]-=P;
w=mul(w,wn[id]);
}
}
}
if(op==-){
for(int i=; i<len/; ++i) swap(y[i],y[len-i]);
LL inv=qpow(len,P-,P);
for(int i=; i<len; ++i) y[i]=mul(y[i],inv);
}
}
LL s[N];
int T,n,m;
LL ans[N];
int num[N],mo[N],fmo[N],root;
int main() {
scanf("%d",&T);
while(T--) {
scanf("%d%d",&n,&m);
root = cal_root(m);
LL cnt0 = ;
memset(ans,,sizeof(ans));
memset(num,,sizeof(num));
for(LL i = , t = ; i < m-; ++i,t=t*root%m)
mo[i] = t,fmo[t] = i;
for(int i = ; i <= n; ++i) {
int x;
scanf("%d",&x);
x%=m;
if(x == ) cnt0++;
else num[fmo[x]]++;
}
for(len = ; len <= (*m-); len<<=);
for(int i = ;i < m; ++i) s[i] = num[i];
for(int i = m; i < len; ++i) s[i] = ;
NTT_init();
NTT(s,);
for(int i = ; i < len; ++i) s[i] = mul(s[i],s[i]);
NTT(s,-);
for(int i = ; i <= *m-; ++i) {
LL now = s[i];
if(i%==) now -= num[i/];
now /= ;
ans[mo[i%(m-)]] += now;
}
printf("%lld\n",(LL)cnt0*(n-cnt0)+(LL)cnt0*(cnt0-)/);
for(int i = ; i < m; ++i) printf("%lld\n",ans[i]);
}
return ;
}
XJTUOJ wmq的A×B Problem FFT/NTT的更多相关文章
- FFT/NTT模板 既 HDU1402 A * B Problem Plus
@(学习笔记)[FFT, NTT] Problem Description Calculate A * B. Input Each line will contain two integers A a ...
- FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅰ
众所周知,tzc 在 2019 年(12 月 31 日)就第一次开始接触多项式相关算法,可到 2021 年(1 月 1 日)才开始写这篇 blog. 感觉自己开了个大坑( 多项式 多项式乘法 好吧这个 ...
- [学习笔记&教程] 信号, 集合, 多项式, 以及各种卷积性变换 (FFT,NTT,FWT,FMT)
目录 信号, 集合, 多项式, 以及卷积性变换 卷积 卷积性变换 傅里叶变换与信号 引入: 信号分析 变换的基础: 复数 傅里叶变换 离散傅里叶变换 FFT 与多项式 \(n\) 次单位复根 消去引理 ...
- FFT/NTT/MTT学习笔记
FFT/NTT/MTT Tags:数学 作业部落 评论地址 前言 这是网上的优秀博客 并不建议初学者看我的博客,因为我也不是很了解FFT的具体原理 一.概述 两个多项式相乘,不用\(N^2\),通过\ ...
- FFT&NTT总结
FFT&NTT总结 一些概念 \(DFT:\)离散傅里叶变换\(\rightarrow O(n^2)\)计算多项式卷积 \(FFT:\)快速傅里叶变换\(\rightarrow O(nlogn ...
- FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅲ
第三波,走起~~ FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅰ FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅱ 单位根反演 今天打多校时 1002 被卡科技了 ...
- FFT \ NTT总结(多项式的构造方法)
前言.FFT NTT 算法 网上有很多,这里不再赘述. 模板见我的代码库: FFT:戳我 NTT:戳我 正经向:FFT题目解题思路 \(FFT\)这个玩意不可能直接裸考的..... 其实一般\(FF ...
- 我的第三篇博客(激动激动真激动!!!)A-B Problem
#210. 差(A-B problem) 题目描述 楠楠在网上刷题,感觉第一题:求两数的和(A+B Problem)太无聊了,于是增加了一题:A-B Problem,难倒了一群小朋友,哈哈. 题目是这 ...
- A-B Problem nyoj
A-B Problem 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 A+B问题早已经被大家所熟知了,是不是很无聊呢?现在大家来做一下A-B吧. 现在有两个实数A和 ...
随机推荐
- 贴一下我写过的c++程序代码
5258 #include <iostream>#include <iomanip>#include <cmath>using namespace std;clas ...
- SQLSERVER 差异备份、全备份
--exec BackUPDatabase_LeeHG语句参数说明: -- 示例:exec BackUPDatabase_LeeHG '参数一','参数二','参数三','参数四','参数五',' 参 ...
- BZOJ 3130 [Sdoi2013]费用流 ——网络流
[题目分析] 很容易想到,可以把P放在流量最大的边上的时候最优. 所以二分网络流,判断什么时候可以达到最大流. 流量不一定是整数,所以需要实数二分,整数是会WA的. [代码] #include < ...
- ubuntu mysql安装及需要其他主机连服务器mysql时的设置(error:10061)
说明: 一个朋友在使用ubuntu-server 16.04安装mysql,设置远程访问的时候出现了问题,请我帮忙.但是,我也没有使用过ubuntu安装mysql,于是乎搜索了很多技术文件,比着葫芦画 ...
- Count on a tree(bzoj 2588)
Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...
- 军训分批(codevs 2751)
题目描述 Description 某学校即将开展军训.共有N个班级. 前M个优秀班级为了保持学习优势,必须和3位任课老师带的班级同一批. 问共有几批? 输入描述 Input Description N ...
- angular中事件戳转日期的格式
本地化日期格式化: ({{ today | date:'medium' }})Nov 19, 2015 3:57:48 PM ({{ today | date:'short' }})11/19/15 ...
- linux 管道符号 | ,以及&& ||等等特殊符号笔记
管道和重导向:“|”.“>”.“>>”.“<” 重导向就是使命令改变它所认定的标准输出.“>”可将结果输出到文件中,该文件原有内容会被删除,“>>”则将结果附 ...
- mysql date_add日期函数的使用
select date_add(CURRENT_DATE()-day(CURRENT_DATE())+1,interval 3 month);##my sql 获取三个月之后的第一天日期select ...
- commons.apache
1.ToStringBuilder //对象及其属性一行显示 System.out.println(ToStringBuilder.reflectionToString(u)); System.out ...