HDU - 6589 Sequence (生成函数+NTT)
设序列a的生成函数$\large f(x)=\sum\limits_{i=0}^{n-1}a_ix^i$,则操作1,2,3分别对应将$f(x)$乘上$\Large\frac{1}{1-x},\frac{1}{1-x^2},\frac{1}{1-x^3}$,如果操作1,2,3分别进行了p1,p2,p3次,则最终序列的生成函数为$\Large\frac{f(x)}{(1-x)^{p_1}(1-x^2)^{p_2}(1-x^3)^{p_3}}$,套个二项式定理+多项式乘法+多项式逆元即可。由于题目中的模数刚好可以NTT,因此直接NTT即可。(ps:浮点数FFT取模常数太大,会TLE)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e5+,M=1e6+,mod=;
const int G=;
int n,m,n2,a[N],b[][N],cnt[],fac[M],inv[M],invf[M];
int Pow(int x,int p) {
int ret=;
for(; p; p>>=,x=(ll)x*x%mod)if(p&)ret=(ll)ret*x%mod;
return ret;
}
int C(int n,int m) {return n<m?:(ll)fac[n]*invf[m]%mod*invf[n-m]%mod;}
struct F_FT {
int A[N],B[N],b[N],c[N];
void FFT(int* a,int n,int f) {
for(int i=,j=n>>,k; i<n-; ++i,j^=k) {
if(i<j)swap(a[i],a[j]);
for(k=n>>; j&k; j^=k,k>>=);
}
for(int k=; k<n; k<<=) {
int gn=Pow(G,(mod-)/(k<<));
if(f==-)gn=Pow(gn,mod-);
for(int i=; i<n; i+=k<<) {
int g=;
for(int j=i; j<i+k; ++j,g=(ll)g*gn%mod) {
int x=a[j],y=(ll)g*a[j+k]%mod;
a[j]=((ll)x+y)%mod,a[j+k]=((ll)x-y+mod)%mod;
}
}
}
if(!~f)for(int i=; i<n; ++i)a[i]=(ll)a[i]*inv[n]%mod;
}
void mul(int* a,int* b,int* c,int n) {
for(int i=; i<n; ++i)A[i]=a[i],B[i]=b[i],A[i+n]=B[i+n]=;
n<<=;
FFT(A,n,),FFT(B,n,);
for(int i=; i<n; ++i)c[i]=(ll)A[i]*B[i]%mod;
FFT(c,n,-);
}
void inverse(int* a,int n) {
for(int i=; i<n; ++i)b[i]=;
b[]=Pow(a[],mod-);
for(int m=; m<=n; m<<=) {
mul(b,b,c,m),mul(a,c,c,m);
for(int i=; i<m; ++i)b[i]=(((ll)b[i]*-c[i])%mod+mod)%mod;
}
for(int i=; i<n; ++i)a[i]=b[i];
}
} fft;
int main() {
fac[]=invf[]=inv[]=;
for(int i=; i<M; ++i)inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
for(int i=; i<M; ++i)fac[i]=(ll)fac[i-]*i%mod,invf[i]=(ll)invf[i-]*inv[i]%mod;
int T;
for(scanf("%d",&T); T--;) {
memset(cnt,,sizeof cnt);
memset(a,,sizeof a);
scanf("%d%d",&n,&m);
n2=;
for(; n2<n; n2<<=);
for(int i=; i<n; ++i)scanf("%d",&a[i]);
while(m--) {
int x;
scanf("%d",&x);
cnt[x-]++;
}
for(int j=; j<; ++j) {
for(int i=; i<n2; ++i)b[j][i]=;
for(int i=; i*(j+)<n2; ++i)b[j][i*(j+)]=(ll)C(cnt[j],i)*(i&?mod-:)%mod;
if(j)fft.mul(b[],b[j],b[],n2);
}
fft.inverse(b[],n2),fft.mul(a,b[],a,n2);
ll ans=;
for(int i=; i<n; ++i)ans^=(ll)a[i]*(i+);
printf("%lld\n",ans);
}
return ;
}
也可以直接利用性质$\Large\frac{1}{(1-x)^n}=\sum\limits_{i=0}^{n}C_{n-1+i}^{i}x^i$,省去了求逆元的过程。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e5+,M=1e6+,mod=;
const int G=;
int n,m,n2,a[N],b[][N],c[N],cnt[],fac[M],inv[M],invf[M];
int Pow(int x,int p) {
int ret=;
for(; p; p>>=,x=(ll)x*x%mod)if(p&)ret=(ll)ret*x%mod;
return ret;
}
int C(int n,int m) {return n<m?:(ll)fac[n]*invf[m]%mod*invf[n-m]%mod;}
struct F_FT {
int A[N],B[N],c[N];
void FFT(int* a,int n,int f) {
for(int i=,j=n>>,k; i<n-; ++i,j^=k) {
if(i<j)swap(a[i],a[j]);
for(k=n>>; j&k; j^=k,k>>=);
}
for(int k=; k<n; k<<=) {
int gn=Pow(G,(mod-)/(k<<));
if(f==-)gn=Pow(gn,mod-);
for(int i=; i<n; i+=k<<) {
int g=;
for(int j=i; j<i+k; ++j,g=(ll)g*gn%mod) {
int x=a[j],y=(ll)g*a[j+k]%mod;
a[j]=((ll)x+y)%mod,a[j+k]=((ll)x-y+mod)%mod;
}
}
}
if(!~f)for(int i=; i<n; ++i)a[i]=(ll)a[i]*inv[n]%mod;
}
void mul(int* a,int* b,int* c,int n) {
for(int i=; i<n; ++i)A[i]=a[i],B[i]=b[i],A[i+n]=B[i+n]=;
n<<=;
FFT(A,n,),FFT(B,n,);
for(int i=; i<n; ++i)c[i]=(ll)A[i]*B[i]%mod;
FFT(c,n,-);
}
} fft;
int main() {
fac[]=invf[]=inv[]=;
for(int i=; i<M; ++i)inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
for(int i=; i<M; ++i)fac[i]=(ll)fac[i-]*i%mod,invf[i]=(ll)invf[i-]*inv[i]%mod;
int T;
for(scanf("%d",&T); T--;) {
memset(cnt,,sizeof cnt);
memset(a,,sizeof a);
scanf("%d%d",&n,&m);
n2=;
for(; n2<n; n2<<=);
for(int i=; i<n; ++i)scanf("%d",&a[i]);
while(m--) {
int x;
scanf("%d",&x);
cnt[x-]++;
}
for(int j=; j<; ++j) {
for(int i=; i<n2; ++i)b[j][i]=;
if(cnt[j]==)b[j][]=;
else for(int i=; i*(j+)<n2; ++i)b[j][i*(j+)]=C(cnt[j]-+i,i);
if(j)fft.mul(b[],b[j],b[],n2);
}
fft.mul(a,b[],a,n2);
ll ans=;
for(int i=; i<n; ++i)ans^=(ll)a[i]*(i+);
printf("%lld\n",ans);
}
return ;
}
HDU - 6589 Sequence (生成函数+NTT)的更多相关文章
- HDU 3397 Sequence operation(线段树)
HDU 3397 Sequence operation 题目链接 题意:给定一个01序列,有5种操作 0 a b [a.b]区间置为0 1 a b [a,b]区间置为1 2 a b [a,b]区间0变 ...
- HDU 5919 Sequence II(主席树+逆序思想)
Sequence II Time Limit: 9000/4500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) To ...
- hdu 5146 Sequence
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5146 Sequence Description Today we have a number sequ ...
- 2018.12.31 bzoj3992: [SDOI2015]序列统计(生成函数+ntt+快速幂)
传送门 生成函数简单题. 题意:给出一个集合A={a1,a2,...as}A=\{a_1,a_2,...a_s\}A={a1,a2,...as},所有数都在[0,m−1][0,m-1][0,m− ...
- HDU 6395 Sequence 【矩阵快速幂 && 暴力】
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6395 Sequence Time Limit: 4000/2000 MS (Java/Others) ...
- bzoj 3992: [SDOI2015]序列统计【原根+生成函数+NTT+快速幂】
还是没有理解透原根--题目提示其实挺明显的,M是质数,然后1<=x<=M-1 这种计数就容易想到生成函数,但是生成函数是加法,而这里是乘法,所以要想办法变成加法 首先因为0和任何数乘都是0 ...
- hdu 5312 Sequence(数学推导——三角形数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5312 Sequence Time Limit: 2000/2000 MS (Java/Others) ...
- hdu 1711Number Sequence (KMP入门,子串第一次出现的位置)
Number Sequence Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- [P5748] 集合划分计数 - 生成函数,NTT
求 \(10^5\) 以内的所有贝尔数:将 \(n\) 个有标号的球划分为若干非空集合的方案数 Solution 非空集合的指数生成函数为 \(F(x)=e^x-1\) 枚举一共用多少个集合,答案就是 ...
随机推荐
- pm2 代替 Supervisor 管理进程
前提 我们在使用 Laravel 的时候不免用到列队来处理任务,而 Laravel 官方文档给出的是 Supervisor 来管理进程和监控.但是我们在使用中有下面几个缺点: Supervisor 单 ...
- PropertyValuesProvider在日期绑定和校验中的应用
Github地址:https://github.com/andyslin/spring-ext 编译.运行环境:JDK 8 + Maven 3 + IDEA + Lombok spring-boot: ...
- Windows 和 Office 大客户激活方法
激活Windows 10 找到Powershell,然后右键管理员身份运行,依次输入下面的命令,注意将$host切换成为你组织的服务器地址: slmgr.vbs -upk slmgr.vbs -ipk ...
- 【机器学习实践】Jupyter Notebook安装 侧边导航栏功能 操作及其他常用扩展功能介绍
安装过程: 1. 首先我们引入jupyter_contrib_nbextension这个第三方库. 2. 在Anaconda Promot中输入命令: pip install jupyter_con ...
- 1.2.2 OSI参考模型 上
一.HCNA网络技术学习指南 为了实现网络的互通及各种各样的网络应用,网络设备需要运行各种各样的协议已实现各种各样具体的功能.面对各种各样且数量繁多的功能,我们可以从网络架构的角度,引入功能分层的模型 ...
- webdriervAPI(下载文件)
from selenium import webdriver driver = webdriver.Chorme() driver.get("http://www.baidu.co ...
- hbase的hue部署和使用
1.组件版本信息 zookeeper hadoop hbase hue zookeeper-3.4.12 hadoop-3.0.3 hbase-2.1.5 4.4.0 2. ...
- sql server 查询某段日期某段时间内的数据
如我要取8月1号到8月30号之间的早上7点半到晚上八点半这段时间内的数据. SELECT * FROM tableName AS tWHERE t.create_date BETWEEN '2017- ...
- CVE-2018-19824漏洞学习
简介 在Linux内核4.19.6之前,本地用户可以通过在Sound / USB /card.c.的usb_audio_probe中错误处理一个恶意USB声音设备(没有接口)来利用ALSA驱动程序中的 ...
- Https接口调用工具类
ClientUtil.java import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org. ...