快速数论变换ntt。

早上才刚刚接触了一下FFT,然后就开始撸这题了,所以要详细地记录一下。

看了这篇巨巨的博客才慢慢领会的:http://blog.csdn.net/cqu_hyx/article/details/52194696

FFT的作用是计算卷积。可以简单的理解为计算多项式*多项式最后得到的多项式,暴力计算是O(n*n)的,FFT可以做到O(nlogn)。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-;
void File()
{
freopen("D:\\in.txt","r",stdin);
freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
char c = getchar(); x = ;while(!isdigit(c)) c = getchar();
while(isdigit(c)) { x = x * + c - ''; c = getchar(); }
} const int maxn=;
const LL mod=;
const LL G=; LL t[maxn],a[maxn],b[maxn],c[maxn],f[maxn],fac[maxn],NI[maxn];
int T,n,m;
LL rev[maxn],N,len,inv; LL POW[maxn],NiPOW[maxn]; LL power(LL x,LL y)
{
LL res=;
for(;y;y>>=,x=(x*x)%mod)
{
if(y&)res=(res*x)%mod;
}
return res;
} void init()
{
while((n+m)>=(<<len))len++;
N=(<<len);
inv=power(N,mod-);
for(int i=;i<N;i++)
{
LL pos=;
LL temp=i;
for(int j=;j<=len;j++)
{
pos<<=;pos |= temp&;temp>>=;
}
rev[i]=pos;
}
} void ntt(LL *a,LL n,LL re)
{
for(int i=;i<n;i++)
{
if(rev[i]>i)
{
swap(a[i],a[rev[i]]);
}
}
for(int i=;i<=n;i<<=)
{
int mid=i>>; LL wn=power(G,(mod-)/i);
if(re) wn=power(wn,(mod-));
for(int j=;j<n;j+=i)
{
LL w=;
for(int k=;k<mid;k++)
{
int temp1=a[j+k];
int temp2=(LL)a[j+k+mid]*w%mod;
a[j+k]=(temp1+temp2);if(a[j+k]>=mod)a[j+k]-=mod;
a[j+k+mid]=(temp1-temp2);if(a[j+k+mid]<)a[j+k+mid]+=mod;
w=(LL)w*wn%mod;
}
}
}
if(re)
{
for(int i=;i<n;i++)
{
a[i]=(LL)a[i]*inv%mod;
}
}
} bool cmp(LL a,LL b) {return a>b;} LL extend_gcd(LL a,LL b,LL &x,LL &y)
{
if(a==&&b==) return -;
if(b==){x=;y=;return a;}
LL d=extend_gcd(b,a%b,y,x);
y-=a/b*x;
return d;
} LL mod_reverse(LL a,LL n)
{
LL x,y;
LL d=extend_gcd(a,n,x,y);
if(d==) return (x%n+n)%n;
else return -;
} int main()
{
fac[]=; for(int i=;i<=;i++) fac[i]=(LL)i*fac[i-]%mod;
for(int i=;i<=;i++) NI[i]=mod_reverse(fac[i],mod);
POW[]=; for(int i=;i<=;i++) POW[i]=(LL)*POW[i-]%mod;
for(int i=;i<=;i++) NiPOW[i]=mod_reverse(POW[i],mod); scanf("%d",&T); while(T--)
{
len=; memset(c,,sizeof c); memset(a,,sizeof a); memset(b,,sizeof b); scanf("%d",&n); m=n;
for(int i=;i<=n;i++) { int x; scanf("%d",&x); t[i]=(LL)x; } sort(t+,t++n,cmp);
for(int i=;i<n;i++)
{
LL x=fac[n]*NI[i]%mod;
a[i]=x*POW[n-i]%mod;
}
for(int i=;i<=n;i++) b[n-i]=t[i]*fac[i-]%mod; init(); ntt(a,N,); ntt(b,N,);
for(int i=;i<=N;i++) c[i]=a[i]*b[i]%mod;
ntt(c,N,); for(int i=;i<n;i++) f[n-i]=c[i]*NI[n]%mod;
for(int i=;i<=n;i++) f[i]=f[i]*NI[i-]%mod;
for(int i=;i<=n;i++) f[i]=f[i]*NiPOW[i]%mod;
LL ans=; for(int i=;i<=n;i++) { ans=(ans+f[i])%mod; printf("%lld ",ans); }
printf("\n");
}
return ;
}

HDU 5829 Rikka with Subset的更多相关文章

  1. HDU 5829 Rikka with Subset(NTT)

    题意 给定 \(n\) 个数 \(a_1,a_2,\cdots a_n\),对于每个 \(K\in[1,n]\) ,求出 \(n\) 个数的每个子集的前 \(K\) 大数的和,输出每个值,对 \(99 ...

  2. HDU 6092`Rikka with Subset 01背包变形

    Rikka with Subset Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  3. HDU 6092 Rikka with Subset

    Rikka with Subset Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  4. hdu 6092 Rikka with Subset(逆向01背包+思维)

    Rikka with Subset Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  5. 2017 ACM暑期多校联合训练 - Team 5 1008 HDU 6092 Rikka with Subset (找规律)

    题目链接 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, s ...

  6. hdu 6092 Rikka with Subset (集合计数,01背包)

    Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...

  7. HDU 6092 Rikka with Subset(dp)

    http://acm.hdu.edu.cn/showproblem.php?pid=6092 题意: 给出两个数组A和B,A数组一共可以有(1<<n)种不同的集合组合,B中则记录了每个数出 ...

  8. hdu 6092 Rikka with Subset(多重背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6092 #include <cstdio> #include <iostream> ...

  9. HDU 6092:Rikka with Subset(dp)

    分析 很多个较小的数字可以随机组合成较大的数字,所以B数组从小到大开始遍历,除了空集,最小的那个存在的个数对应的数字必然是a数组中的数字. 每求出这一部分之后,更新后续的B序列. 分析完后,主要的难点 ...

随机推荐

  1. [ios] NSURL

    NSLog(@“Scheme: %@”, [url scheme]); NSLog(@“Host: %@”, [url host]); NSLog(@“Port: %@”, [url port]); ...

  2. Perception(0-1.1)

    The perception modules run in the context of the process Cognition. They detect features in the imag ...

  3. CodeForces 645B Mischievous Mess Makers

    简单题. 第一次交换$1$和$n$,第二次交换$2$和$n-1$,第三次交换$3$和$n-2$.....计算一下就可以了. #pragma comment(linker, "/STACK:1 ...

  4. JavaScript HTML DOM 元素(节点)

    添加和删除节点(HTML 元素) 创建新的 HTML 元素  如需向 HTML DOM 添加新元素,您必须首先创建该元素(元素节点),然后向一个已存在的元素追加该元素. 例如:这段代码创建新的 < ...

  5. 希腊字母、拉丁字母、Markdown、拼写与读音中英对照表

    大写 小写 中文名 英文 大写Markdown 小写Markdown 意义 阿尔法 Alpha A \alpha 角度.系数.角加速度.第一个.电离度.转化率 贝塔/毕塔 Beta B \beta 磁 ...

  6. CentOS 手动增加、删除swap区

    SWAP是Linux中的虚拟内存,用于扩充物理内存不足而用来存储临时数据存在的.它类似于Windows中的虚拟内存.在Windows中,只可以使用文件来当作虚拟内存.而linux可以文件或者分区来当作 ...

  7. zabbix 布署实践【1 server安装】

    通过openstack环境,开通了2台只有根分区的虚拟机,   目的是为了监控公司所有的物理机,网络设备,虚拟机,总计300个台以上,推荐配置,zabbix官方文档是有给出指引的   环境:CentO ...

  8. 通过反射获取所有的Action 一般用于权限管理

    public IList<ActionPermission> GetAllActionByAssembly() { var result = new List<ActionPermi ...

  9. vga显示彩条

    vga显示驱动程序可分为扫描行列和行列同步两个部分 //注意:只有在有效区域内给vga赋值才会有颜色变化 assign vga_b = isready ? vga_s[:] :'d0; assign ...

  10. 手机浏览器wap网页点击链接触发颜色区块的问题解决办法

    引子 在做HTML5 WAP网页的时候,一行内容做了2个链接,点击一个标签的时候,整个颜色块会闪一下,影响美观.需求针对这种情况来问我,能否把这个一闪的颜色去掉.我当时就想,这个怎么去?那我也不好直接 ...