牛客挑战赛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 ...
随机推荐
- CentOS 7 bonding模式双网卡绑定
1.1 查看系统内核是否支持bonding [root@cobbler-node1 ~]# cat /boot/config-3.10.0-693.el7.x86_64 | grep -i bo ...
- JavaScript对象创建的九种方式
1.标准创建对象模式 var person = new Object(); person.name = "Nicholas"; person.age = 29; person.jo ...
- python 正则表达式与JSON字符串
目录 正则表达式 概括单字符集 匹配单字符 匹配字符集 普通字符与元字符 元字符和普通的字符的混用 数量词{整数|*|+|?} 匹配指规则的字母 贪婪模式 匹配指定长度的字符串 非贪婪模式 匹配指定长 ...
- python 2.7版本解决TypeError: 'encoding' is an invalid keyword argument for this function
今天在用yaml处理数据时,由于yaml.load可接收一个byte字符串,unicode字符串,打开的二进制文件或文本文件对象,但字节字符串和文件必须是utf-8,utf-16-be或utf-16- ...
- 51nod 1202 不同子序列个数(计数DP)
1202 子序列个数 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 子序列的定义:对于一个序列a=a[1],a[2],......a[n].则非空序列a'=a[p1],a ...
- 【Trapping Rain Water】cpp
题目: Given n non-negative integers representing an elevation map where the width of each bar is 1, co ...
- Spring MVC与jQuery结合使用Ajax技术
gradle配置 group 'org.zln.webDemo' version '1.0-SNAPSHOT' apply plugin: 'java' apply plugin: 'jetty' s ...
- iOS App启动图不显示的解决办法.
1. 正常来说,启动图以及App图标需按照命名规则命名, 但是命名不规范并不影响显示; 2. 设置启动图的两种方法: (1) iOS 8—xcode 6 之后新出LaunchScreen.s ...
- 【bzoj3280】小R的烦恼 费用流
题目描述 小R最近遇上了大麻烦,他的程序设计挂科了.于是他只好找程设老师求情.善良的程设老师答应不挂他,但是要求小R帮助他一起解决一个难题. 问题是这样的,程设老师最近要进行一项邪恶的实验来证明P=N ...
- Quotes
A man's gotta do what a man's gotta do.