51nod 1172 Partial Sums V2
题目
给出一个数组A,经过一次处理,生成一个数组S,数组S中的每个值相当于数组A的累加,比如:A = {1 3 5 6} => S = {1 4 9 15}。如果对生成的数组S再进行一次累加操作,{1 4 9 15} => {1 5 14 29},现在给出数组A,问进行K次操作后的结果。(输出结果 Mod 10^9 + 7)
分析
发现,每次处理相当于将A卷上一个\(I(\forall a_i=1)\)
于是机智的我在wiki又发现狄利克雷卷积满足交换律(我居然才知道)
于是快速幂咯,时间复杂度\(O(nlog^2n)\),常数巨大,在51nod的老爷机上根本过不了。
然后就TLE得一塌糊涂。
于是找规律,发现\(ans_k=\sum_{i+j=k}A_iC_{j+n-1}^{j}\)
然后NTT
但是,\(10^9+7\)并没有原根,所以祭出三模数NTT(如果有人想用高精度,我也没办法)。
因为\((10^9+7)^2*n\approx10^{23}\),所以找三个\(10^9\)左右的模数。
假设
\]
\]
\]
因为\(m_0m_1m_2\)会爆long long
所有,通过CRT(中国剩余定理)合并前两项,于是\(M=m_0*m_1\)
\]
\]
设\(ans=kM+A\)
因为$$kM+A≡ans≡a_2(mod\ m_2)$$
所以$$k≡(a_2-A)M^{-1}(mod\ m_2)$$
那么根据上面的式子求出k,通过\(kM+A=ans\)就可以求出ans了。
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <bitset>
#include <set>
const int maxlongint=2147483647;
const long long mo=1e9+7;
const int N=200005;
using namespace std;
long long mod[3]={469762049,998244353,1004535809},M=mod[0]*mod[1],W[3][N];
long long f[3][N],g[3][N],v[3][N],v_[N],jc[3][N],ny[3][N],inv[N];
int n,m,fn;
long long poww(long long x,long long y,int z)
{
long long s=1;
x%=mod[z];
for(;y;x=x*x%mod[z],y>>=1)
if(y&1) s=s*x%mod[z];
return s;
}
long long mul(long long x,long long y,long long mo)
{
long long s=0;
x%=mo;
for(;y;x=(x+x)%mo,y>>=1)
if(y&1) s=(s+x)%mo;
return s;
}
void NTT(long long *f,int type,int z)
{
for(int i=0,p=0;i<fn;i++)
{
if(i<p) swap(f[i],f[p]);
for(int j=fn>>1;(p^=j)<j;j>>=1);
}
for(int i=2;i<=fn;i<<=1)
{
int half=i>>1,pe=fn/i;
for(int j=0;j<half;j++)
{
long long w=!type?W[z][j*pe]:W[z][fn-j*pe];
for(int k=j;k<fn;k+=i)
{
long long x=f[k],y=f[k+half]*w%mod[z];
f[k]=(x+y)%mod[z],f[k+half]=(x-y+mod[z])%mod[z];
}
}
}
if(type)
{
long long ni=poww(fn,mod[z]-2,z);
for(int i=0;i<fn;i++) f[i]=f[i]*ni%mod[z];
}
}
long long CRT(long long a0,long long a1,long long a2)
{
long long n0=poww(mod[1],mod[0]-2,0),n1=poww(mod[0],mod[1]-2,1);
long long A=(mul(a0*mod[1]%M,n0%M,M)+mul(a1*mod[0]%M,n1%M,M))%M,n2=poww(M%mod[2],mod[2]-2,2);
long long k=(a2-A)%mod[2]*n2%mod[2];
k=(k%mod[2]+mod[2])%mod[2];
return (k%mo*(M%mo)%mo+A)%mo;
}
int main()
{
scanf("%d%d",&n,&m);
for(fn=1;fn<=n*2+2;fn<<=1);
inv[0]=inv[1]=1;
for(int i=2;i<=fn;i++) inv[i]=(-(mo/i)*inv[mo%i]%mo+mo)%mo;
for(int i=0;i<n;i++) scanf("%lld",&f[0][i]),f[1][i]=f[2][i]=f[0][i];
for(int j=0;j<3;j++)
{
W[j][0]=1,W[j][1]=poww(3,(mod[j]-1)/fn,j);
for(int i=2;i<=fn;i++) W[j][i]=W[j][i-1]*W[j][1]%mod[j];
for(int i=0;i<n;i++) v[j][i]=1;
g[j][0]=1;
for(int i=1;i<n;i++) g[j][i]=g[j][i-1]*(i+m-1)%mo*inv[i]%mo;
}
for(int j=0;j<3;j++)
{
NTT(f[j],0,j),NTT(g[j],0,j);
for(int i=0;i<fn;i++) f[j][i]=f[j][i]*g[j][i]%mod[j];
NTT(f[j],1,j);
}
for(int i=0;i<n;i++) printf("%lld\n",CRT(f[0][i],f[1][i],f[2][i]));
}
51nod 1172 Partial Sums V2的更多相关文章
- 51nod 1172 Partial Sums V2 卡精度的任意模数FFT
卡精度的任意模数fft模板题……这道题随便写个表就能看出规律来(或者说考虑一下实际意义),反正拿到这题之后,很快就会发现他是任意模数fft模板题.然后我就去网上抄了一下板子……我打的是最土的任意模数f ...
- 51nod1172 Partial Sums V2
推一下式子发现是裸的FFT,$ans[k]=\sum_{i}\sum_{j}[i+j=k]a[i]*C_{m-1+j}^{j}$ 比较坑爹的就是这个模数,于是我们上任意模数的FFT 任意模数的FFT目 ...
- 51nod 1161 Partial Sums
给出一个数组A,经过一次处理,生成一个数组S,数组S中的每个值相当于数组A的累加,比如:A = {1 3 5 6} => S = {1 4 9 15}.如果对生成的数组S再进行一次累加操作,{1 ...
- 51nod1161 Partial Sums
开始想的是O(n2logk)的算法但是显然会tle.看了解题报告然后就打表找起规律来.嘛是组合数嘛.时间复杂度是O(nlogn+n2)的 #include<cstdio> #include ...
- Non-negative Partial Sums(单调队列)
Non-negative Partial Sums Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/32768 K (Jav ...
- hdu 4193 Non-negative Partial Sums 单调队列。
Non-negative Partial Sums Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/32768 K (Jav ...
- TOJ 1721 Partial Sums
Description Given a series of n numbers a1, a2, ..., an, the partial sum of the numbers is defined a ...
- 【计数】cf223C. Partial Sums
考试时候遇到这种题只会找规律 You've got an array a, consisting of n integers. The array elements are indexed from ...
- CodeForces 223C Partial Sums 多次前缀和
Partial Sums 题解: 一个数列多次前缀和之后, 对于第i个数来说他的答案就是 ; i <= n; ++i){ ; j <= i; ++j){ b[i] = (b[i] + 1l ...
随机推荐
- [转帖]Xenix — 微软与UNIX的短暂爱恋
Xenix — 微软与UNIX的短暂爱恋 https://www.linuxdashen.com/xenix-微软与unix的短暂爱恋 原来微软曾经 干过那么牛B的 unix系统. 微软向外宣布Mic ...
- 查找担保圈-step7-提取未被包含过组的成员,得出结论
USE [test] GO /****** Object: StoredProcedure [dbo].[p05_get_group_member_cleared] Script Date: 2019 ...
- Java笔记1: 输入输出与变量常量
输入方法 nextLine 以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符. 可以获得空白的一串字符. import java.util.Scanner; pu ...
- C语言 --- 初级指针
1.内存的访问:直接访问,间接访问. 直接访问:int a = 0;直接对a赋值.选一个内存地址,让他存20这个数. a += 10; ...
- GET POST请求区别
cookie .session.tokencookie:存放在浏览器相关的硬盘文件中session:存放在服务器端的内存中,退出后,被清空token:服务器端生成后,不保存,发给客户端,客户端的hea ...
- frp基础操作
[common]privilege_mode = true privilege_token = ****bind_port = 7000 dashboard_user = 444444dashboar ...
- ES6新特性总结
一.let const var有缺陷:有块级作用域.能重复定义.无法限制修改.所以出来了let和const. 有块级作用域,不能重复定义 const不能修改,必须定义的时候赋值 二.解构赋值 1.左右 ...
- ASP.NET 打包发布中没有Visual Studio Installer
环境:win7 64位 : VisualStudio2015 问题描述 创建安装程序时,VisualStudio中没有打包安装程序的Visual Studio Installer功能 解决方法 下载V ...
- MYSQL 创建数据库以及表
创建数据库,表 创建一个数据库,再在数据库下创建一个或多个表,不难,记不住的同学可以直接copy,慢慢的用会即刻,懂的同学请看代码,没有太多基础的同学,除了看代码,请看最下方的知识点 创建数据库: C ...
- Java注解【五、注解实战】
需求: 1.表:用户ID,用户名,年龄,邮箱. 2.实现方法,传入实体,打印sql. 实现: 1.表: package Annotation; @Table("user") pub ...