牛客挑战赛14-F细胞
https://www.nowcoder.com/acm/contest/81/F
循环卷积的裸题,太久没做FFT了,这么裸的循环卷积都看不出来
注意一下本文的mod 都是指表示幂的模数,而不是NTT用到的模数
- 首先我们先不管m,考虑多项式
可以发现这个是一个多项式的n次幂,正常求一个多项式的n次幂,可以用快速幂套NTT,复杂度n*log(n)*log(n), 最多只能做n在1e4左右的题。
- 现在在来考虑m,则原式为。
显然这就是循环卷积的常见形式
如果先用快速幂套NTT 把多项式系数算出来a[i], 再对i%mod同余的系数进行累加,时间和空间都是会爆炸的。
不过在多项式快速幂实现的时候不难发现,可以每做一次多项式乘法,就对幂取余一次,合并幂的余数相同的项。这样空间可以降到2*mod, 时间复杂度 mod*log(mod)*log(n) 但是这样还是会超时的
- 最后重点来了,上面是一般的情况的下循环卷积的做法,循环卷积还有一种特殊情况,就是指数的mod=2^m 时,这时循环卷积可以直接变成频域上的2^m-1 次多项式的点乘(注意要系数等于2^m-1 的点乘, 不需要先以前一样开两倍大小,以防止多项式系数溢出,这里就是要溢出才能保证正确性),这时可以发现,NTT 前可NTT后都是mod-1次多项,没有系数合并的那一步,所以干脆中间乘的时候,就不要NTT回来, 直接在点成的时候做快速幂。 这样只需做一次NTT和逆NTT.时间复杂度 mod*(log(n)+log(mod))
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
#define N 2000005
ll a[N],b[N];
const ll PMOD=;
const ll PR=;
static ll qp[];
ll res[N];
struct NTT__container
{
NTT__container()
{
int t,i;
for( i=; i<; i++)///注意循环上界与2n次幂上界相同
{
t=<<i;
qp[i]=quick_pow(PR,(PMOD-)/t);
}
}
ll quick_pow(ll x,ll n)
{
ll ans=;
while(n)
{
if(n&)
ans=ans*x%PMOD;
x=x*x%PMOD;
n>>=;
}
return ans;
}
int get_len(int n)///计算刚好比n大的2的N次幂
{
int i,len;
for(i=(<<); i; i>>=)
{
if(n&i)
{
len=(i<<);
break;
}
}
return len;
}
inline void NTT(ll F[],int len,int type)
{
int id=,h,j,k,t,i;
ll E,u,v;
for(i=,t=; i<len; i++)///逆位置换
{
if(i>t) swap(F[i],F[t]);
for(j=(len>>); (t^=j)<j; j>>=);
}
for( h=; h<=len; h<<=)///层数
{
id++;
for( j=; j<len; j+=h)///遍历这层上的结点
{
E=;///旋转因子
for(int k=j; k<j+h/; k++)///遍历结点上的前半序列
{
u=F[k];///A[0]
v=(E*F[k+h/])%PMOD;///w*A[1]
///对偶计算
F[k]=(u+v)%PMOD;
F[k+h/]=((u-v)%PMOD+PMOD)%PMOD;
///迭代旋转因子
E=(E*qp[id])%PMOD;///qp[id]是2^i等分因子
}
}
}
if(type==-)
{
int i;
ll inv;
for(i=; i<len/; i++)///转置,因为逆变换时大家互乘了对立点的因子
swap(F[i],F[len-i]);
inv=quick_pow(len,PMOD-);///乘逆元还原
for( i=; i<len; i++)
F[i]=(F[i]%PMOD*inv)%PMOD;
}
}
inline void inv(ll *a,int len)///答案存在res中
{
if(len==)
{
res[]=quick_pow(a[],PMOD-);
return ;
}
inv(a,len>>);///递归
static ll temp[N];
memcpy(temp,a,sizeof(ll)*(len>>));
NTT(temp,len,);
NTT(res,len,);
int i;
for(i=; i<len; i++)
res[i]=res[i]*(-temp[i]*res[i]%PMOD+PMOD)%PMOD;///多项式逆元迭代公式
NTT(res,len,-);
memset(res+(len>>),,sizeof(ll)*(len>>));
}
void mul(ll x[],ll y[],int len)///答案存在x中
{
int i;
NTT(x,len,);///先变换到点值式
NTT(y,len,);///先变换到点值式上
for(i=; i<len; i++)
x[i]=(x[i]*y[i])%PMOD;///在点值上点积
NTT(x,len,-);///再逆变换回系数式
} } cal;
void print(ll a[],int len)
{
int high=,i;
for(i=len-; i>=; i--)
{
if(a[i])
{
high=i;
break;
}
}
for(i=high; i>=; i--)putchar(a[i]+'');
puts("");
}
int main()
{
int m,i,j,k,len;
long long n;
// printf("%lld\n",PMOD);
scanf("%lld%d",&n,&m);
len=<<m;
a[]=;
a[]=;
cal.NTT(a,len,);
for(i=;i<len;i++)
{
a[i]=cal.quick_pow(a[i],n);
}
cal.NTT(a,len,-);
long long temp=,ans=;
for(i=;i<len;i++)
{
ans+=temp*a[i]%PMOD;
temp=temp*%PMOD;
}
printf("%lld\n",ans%PMOD);
return ;
}
牛客挑战赛14-F细胞的更多相关文章
- 牛客挑战赛33 F 淳平的形态形成场(无向图计数,EGF,多项式求逆)
传送门: 淳平的形态形成场 题解: 把a排序后,直接统计答案恰好为a[i]并不好做,可以统计答案>a[i]的方案数,设为\(f[i]\). 即不存在一个联通块,所有的权值都<=a[i]. ...
- 牛客练习赛3 F - 监视任务
链接:https://www.nowcoder.net/acm/contest/13/F来源:牛客网 题目描述
- 牛客网 牛客练习赛43 F.Tachibana Kanade Loves Game-容斥(二进制枚举)+读入挂
链接:https://ac.nowcoder.com/acm/contest/548/F来源:牛客网 Tachibana Kanade Loves Game 时间限制:C/C++ 1秒,其他语言2秒 ...
- 牛客练习赛16 F 选值【二分/计数】
链接:https://www.nowcoder.com/acm/contest/84/F 来源:牛客网 题目描述 给定n个数,从中选出三个数,使得最大的那个减最小的那个的值小于等于d,问有多少种选法. ...
- 牛客练习赛14 D 比较月亮大小 【水】
链接:https://www.nowcoder.com/acm/contest/82/D 来源:牛客网 比较月亮大小 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其 ...
- 牛客练习赛14 B 区间的连续段 (倍增)
链接:https://ac.nowcoder.com/acm/contest/82/B来源:牛客网 区间的连续段 时间限制:C/C++ 7秒,其他语言14秒 空间限制:C/C++ 262144K,其他 ...
- 牛客练习赛14 D比较月亮大小 (实现)
链接:https://ac.nowcoder.com/acm/contest/82/D来源:牛客网 题目描述 点点是一名出色的狼人.众所周知,狼人只有在满月之夜才会变成狼. 同时,月亮的大小随着时间变 ...
- 2020牛客竞赛 DP F 碎碎念
作者:儒生雄才1链接:https://ac.nowcoder.com/discuss/366644来源:牛客网 题目连接:https://ac.nowcoder.com/acm/contest/300 ...
- 牛客挑战赛 39 牛牛与序列 隔板法 容斥 dp
LINK:牛牛与序列 (牛客div1的E题怎么这么水... 还没D难. 定义一个序列合法 当且仅当存在一个位置i满足 $a_i>a_,a_j<a_$且对于所有的位置i,$1 \leq a_ ...
- 牛客练习赛14 E - 无向图中的最短距离 (bfs+bitset)
一个链接:https://ac.nowcoder.com/acm/contest/82/E来源:牛客网 无向图中的最短距离 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144 ...
随机推荐
- 将xml转为array 输出xml字符
//将xml转为array private function fromXml($xml){ // 禁止引用外部xml实体 libxml_disable_entity_loader(true); ret ...
- bootmem API总结
bootmem_init()函数执行完成后,linux启动初期的bootmem分配器就初始化完成了,可以调用bootmem提供的API分配内存. 这些API在include/linux/bootmem ...
- POJ 2586 贪心+枚举
Y2K Accounting Bug Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 15626 Accepted: 78 ...
- linux 查看CPU内存 网络 流量 磁盘 IO
使用vmstat命令来察看系统资源情况 在命令行方式下,如何查看CPU.内存的使用情况,网络流量和磁盘I/O? Q: 在命令行方式下,如何查看CPU.内存的使用情况,网络流量和磁盘I/O? A: 在命 ...
- JMX浅谈
一 JMX 是什么? JMX(Java Management Extensions,即Java管理扩展) JMX在Java编程语言中定义了应用程序以及网络管理和监控的体系结构.设计模式.应用程序接口以 ...
- kettle Spoon.bat闪退解决办法!
1.Java环境配置问题: java_home:D:\Program Files\Java\jdk1.7.0_25(安装jdk路径) classpath:.;%java_home%\lib\dt.ja ...
- ZeroClipboard_copy
//<script src="js/ZeroClipboard.js" type="text/javascript"></script> ...
- loj2059 「TJOI / HEOI2016」字符串
字符串好难啊不会啊 #include <iostream> #include <cstdio> using namespace std; int n, m, rnk[10000 ...
- Asp.net自定义控件开发任我行(3)-Render
摘要 上一篇我们讲到了自定义标签TagPrefix用法,此篇我们来讲一下控件的呈现,主要是呈现下拉框 内容 呈现的方法有,Render,RenderControl,RenderChildren,这三个 ...
- Careercup - Microsoft面试题 - 5188169901277184
2014-05-12 06:12 题目链接 原题: Write a function to retrieve the number of a occurrences of a substring(ev ...