P5488 差分与前缀和 NTT Lucas定理 多项式
LINK:差分与前缀和
这道题和loj的一个人的高三楼相似。
也略有不同 先考虑前缀和:设G(x)为原式的普通型生成函数 \(F(x)=1+x+x^2+...\)
那么其实求的是 \(G(x)*(F(x))^k\)的前n项。k很大 不能直接做多项式快速幂 想直接展开系数似乎也做不到。
利用Lucas定理 \(F(x)^k\equiv F(x)^{sp+r}\equiv F(x)^{sp}*F(x)^r (mod p)\)
后面的东西再次展开\((F(x)^p)^s*F(x)^r\) 忘了一件事情为了方便设\(F(x)=1+x\)
那么显见\(((1+x)^p)^s*F(x)^r=(1+x^p)^s*F(x)^r\)
由于最后求出前n项 所以上式等价于\(F(x)^r\)
其实这里取的\(F(x)\)有点特殊了实际上\(F(x)=\frac{1}{1-x}\)也是一样的。
对于差分也同理 所以可以使k直接对mod取模。
其实根据上式还可以反向证明Lucas定理 这里不再赘述。
考虑如何求出系数 可以使用多项式快速幂 也可以选择EXP那一套 当然最直观的是第i项系数为\(C(i+k-1,k-1)\)可以直接线性递推得到。
差分同理 至此问题得到解决。
//#include<bits\stdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define gc(a) scanf("%s",a+1)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define P 1000000007
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-8
#define sq sqrt
#define S second
#define F first
#define mod 1004535809
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
RE int x=0,f=1;RE char ch=getc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
while(ch>='0'&&ch<='9'){x=((ll)x*10+ch-'0')%mod;ch=getc();}
return x*f;
}
const int MAXN=300010,G=3;
int n,k,T,lim;
int a[MAXN],rev[MAXN];
int b[MAXN],O[MAXN],in[MAXN];
inline int ksm(int b,int p)
{
int cnt=1;
while(p)
{
if(p&1)cnt=(ll)cnt*b%mod;
b=(ll)b*b%mod;p=p>>1;
}
return cnt;
}
inline void NTT(int *a,int op)
{
vep(0,lim,i)if(i<rev[i])swap(a[i],a[rev[i]]);
for(int len=2;len<=lim;len=len<<1)
{
int mid=len>>1;
int wn=ksm(G,op==1?(mod-1)/len:mod-1-(mod-1)/len);
vep(1,mid,i)O[i]=(ll)O[i-1]*wn%mod;
for(int j=0;j<lim;j+=len)
{
vep(0,mid,i)
{
int x=a[i+j],y=(ll)a[i+j+mid]*O[i]%mod;
a[i+j]=(x+y)%mod;a[i+j+mid]=(x-y+mod)%mod;
}
}
}
if(op==-1)
{
int INV=ksm(lim,mod-2);
vep(0,lim,i)a[i]=(ll)a[i]*INV%mod;
}
}
int main()
{
freopen("1.in","r",stdin);
get(n);get(k);get(T);O[0]=1;
vep(0,n,i)get(a[i]);
if(T==0)
{
in[1]=b[0]=1;b[1]=k;
vep(2,n,i)
{
in[i]=(ll)in[mod%i]*(mod-mod/i)%mod;
b[i]=(ll)b[i-1]*in[i]%mod*(i+k-1)%mod;
}
}
else
{
in[1]=b[0]=1;b[1]=mod-k;
rep(2,min(k,n-1),i)
{
in[i]=(ll)in[mod%i]*(mod-mod/i)%mod;
b[i]=mod-(ll)b[i-1]*in[i]%mod*(k-i+1)%mod;
}
}
lim=1;while(lim<n+n)lim=lim<<1;
vep(0,lim,i)rev[i]=rev[i>>1]>>1|((i&1)?lim>>1:0);
NTT(a,1);NTT(b,1);
vep(0,lim,i)a[i]=(ll)a[i]*b[i]%mod;
NTT(a,-1);
vep(0,n,i)printf("%d ",a[i]);
return 0;
}
P5488 差分与前缀和 NTT Lucas定理 多项式的更多相关文章
- FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅰ
众所周知,tzc 在 2019 年(12 月 31 日)就第一次开始接触多项式相关算法,可到 2021 年(1 月 1 日)才开始写这篇 blog. 感觉自己开了个大坑( 多项式 多项式乘法 好吧这个 ...
- uoj86 mx的组合数 (lucas定理+数位dp+原根与指标+NTT)
uoj86 mx的组合数 (lucas定理+数位dp+原根与指标+NTT) uoj 题目描述自己看去吧( 题解时间 首先看到 $ p $ 这么小还是质数,第一时间想到 $ lucas $ 定理. 注意 ...
- 【BZOJ-4591】超能粒子炮·改 数论 + 组合数 + Lucas定理
4591: [Shoi2015]超能粒子炮·改 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 95 Solved: 33[Submit][Statu ...
- LuoguP5488 差分与前缀和
题意 给定一个长为\(n\)的序列\(a\),求出其\(k\)阶差分或前缀和.结果的每一项都需要对\(1004535809\)取模. 打表找规律 先看前缀和,设\(n=5\),\(k=4\),按照阶从 ...
- 组合数取模及Lucas定理
引入: 组合数C(m,n)表示在m个不同的元素中取出n个元素(不要求有序),产生的方案数.定义式:C(m,n)=m!/(n!*(m-n)!)(并不会使用LaTex QAQ). 根据题目中对组合数的需要 ...
- 【算法学习笔记】组合数与 Lucas 定理
卢卡斯定理是一个与组合数有关的数论定理,在算法竞赛中用于求组合数对某质数的模. 第一部分是博主的个人理解,第二部分为 Pecco 学长的介绍 第一部分 一般情况下,我们计算大组合数取模问题是用递推公式 ...
- 【HDU 3037】Saving Beans Lucas定理模板
http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...
- CF451E Devu and Flowers (隔板法 容斥原理 Lucas定理 求逆元)
Codeforces Round #258 (Div. 2) Devu and Flowers E. Devu and Flowers time limit per test 4 seconds me ...
- 大组合数:Lucas定理
最近碰到一题,问你求mod (p1*p2*p3*……*pl) ,其中n和m数据范围是1~1e18 , l ≤10 , pi ≤ 1e5为不同的质数,并保证M=p1*p2*p3*……*pl ≤ 1e18 ...
随机推荐
- 灵魂代码分享HTML元素标签语义化及使用场景实用到爆
灵魂三问: 标签语义化是什么?为什么要标签语义化?标签语义化使用场景有哪些? 下面让我们跟着这三个问题来展开一下本文的内容. 一.标签语义化是什么? 标签语义化就是让元素标签做适当的事情.例如 p 标 ...
- html/css解决inline-block内联元素间隙的多种方法总汇
序 display有几种属性:inline是内联对象,比如<a/> . <span/>标签等,可以“堆在一起”显示,宽高由内容决定,不能设置:block是块对象,比如<d ...
- 冷知识:达夫设备(Duff's Device)效率真的很高吗?
ID:技术让梦想更伟大 作者:李肖遥 wechat链接:https://mp.weixin.qq.com/s/b1jQDH22hk9lhdC9nDqI6w 相信大家写业务逻辑的时候,都是面向if.el ...
- BZOJ 2200 道路与航线(图论)
BZOJ 2200 道路与航线 题目大意 有两种路,一种没负数,一种没环,求单源最短路. solution 存在负边权Dij一定不能用嘛,显然不是 根据题意能看出来是tarjan,将双向边缩点,得到的 ...
- redis zset底层实现原理
一.Zset编码的选择 1.有序集合对象的编码可以是ziplist或者skiplist.同时满足以下条件时使用ziplist编码: 元素数量小于128个 所有member的长度都小于64字节 其他: ...
- Let's GO(一)
近来开始学Go,留此博客以记录学习过程,顺便鞭策自己更加努力. 人生苦短,Let's GO! Let's GO(一) Let's GO(二) Let's GO(三) Let's GO(四) 简单介绍 ...
- 题解:2018级算法第四次上机 C4-最小乘法
题目描述: 样例: 实现解释: 和字符串处理结合的动态规划,个人认为比较难分析出状态转移方程,虽然懂了之后挺好理解的 知识点: 动态规划,字符串转数字 题目分析: 首先按照最基础:依据题意设计原始dp ...
- Java面向对象详解-下
一. static static:静态的,可以用来修饰属性.方法.代码块(或初始化块).内部类 static修饰属性(类变量): 由类创建的所有的对象,都共用这一个属性 当其中一个对象对此属性进行修改 ...
- [ArcEngine二次开发]为Feature的属性赋值
在创建FeatureClass之后,需要为FeatureClass添加Features,在为Feature的字段赋值时,代码大致如下: 在这里赋值的时候,出现了一个错误: The operation ...
- CSS-好玩的样式(用高斯模糊制作平缓突起)
一.效果图: 应用: 二.上代码 <!DOCTYPE html> <html lang="en"> <head> <meta charse ...