• Loj #6261. 一个人的高三楼


    link : https://loj.ac/problem/6261

    一看就是一个已经退役的大佬出的题。。。

    我一开始还是too young了,忘了看时限,,以为NTT+多项式快速幂就能水过的。。。

    于是就写了个我代码里被我注释掉的东西。。。。。

    后来被卡了之后才想起来全是1的多项式的N次方的各个项的系数是可以直接用组合数算出来的。。。。

    具体的说,设 A = {1,x,x^2,,,,,,,} ^ N 。

    A中的 x^i 的系数就是 C(N+i-1,i) ,因为这就是可重组合的定义式吧23333。

    而根据组合数的通项公式,我们可以很容易的从 x^i 的系数来递推 x^(i+1) 的系数。

    O(N)  计算出 A 之后,直接一遍NTT 让 a卷一下它,得到结果。

    写的时候犯了很多SB错误,想想都想打自己23333.

        1.一开始求补0之后序列长度的逆元求成补0之前的了,,,虽然这个样例并不能看出来因为样例 4=2^2   2333.

        2. 数组大小一定要开到 > 卷积后最高次数 的最小的 2^k 。

       3.K比较大,,,乘积的时候得先%ha之后再运算233

    #include<bits/stdc++.h>
    #define ll long long
    #define maxn 400005 
    using namespace std;
    const int ha=998244353;
    const int root=3;
    const int inv=ha/3+1;
    ll k;
    int a[maxn],b[maxn],n,N;
    int INV,e[maxn],r[maxn],l;
    int object[2][maxn];
    int ni[maxn];
    
    inline int ksm(int x,int y){
    	int an=1;
    	for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha;
    	return an;
    }
    
    inline int add(int x,int y){
    	x+=y;
    	return x>=ha?x-ha:x;
    }
    
    inline void NTT(int *c,int f){
    	for(int i=0;i<N;i++) if(i<r[i]) swap(c[i],c[r[i]]);
    	
    	for(int i=1,o=1;i<N;i<<=1,o++){
    		int omega=object[f==-1][o];
    
    		for(int p=i<<1,j=0;j<N;j+=p){
    			int now=1;
    			for(int u=0;u<i;u++,now=now*(ll)omega%ha){
    				int x=c[j+u],y=c[j+u+i]*(ll)now%ha;
    				c[j+u]=add(x,y);
    				c[j+u+i]=add(x,ha-y);
    			}
    		}
    	}
    	
    	if(f==-1) for(int i=0;i<N;i++) c[i]=c[i]*(ll)INV%ha;
    }
    
    inline void calc(){
    	b[0]=1;
    	for(int i=1;i<n;i++) b[i]=b[i-1]*((ll)(k+i-1)%ha)%ha*(ll)ni[i]%ha;
    }
    
    inline void solve(){
    	int len=(n-1)<<1;
    	for(N=1,l=0;N<=len;N<<=1) l++;
    	for(int i=0;i<N;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    	for(int i=1;i<=l;i++){
    		object[0][i]=ksm(root,(ha-1)/(1<<i));
    		object[1][i]=ksm(inv,(ha-1)/(1<<i));
    	}
    	INV=ksm(N,ha-2);
    	ni[1]=1;
    	for(int i=2;i<=n;i++) ni[i]=-ni[ha%i]*(ll)(ha/i)%ha+ha;
    	
    	calc();
    	
    	/*
    	while(k){
    		if(k&1){
    			NTT(a,1),NTT(b,1);
    			for(int i=0;i<N;i++) a[i]=a[i]*(ll)b[i]%ha;
    			NTT(a,-1),NTT(b,-1);
    			fill(a+n,a+N,0);
    		}
    		
    		NTT(b,1);
    		for(int i=0;i<N;i++) b[i]=b[i]*(ll)b[i]%ha;
    		NTT(b,-1);
    		fill(b+n,b+N,0);
    		k>>=1;
    	}
    	*/
    	
    	NTT(a,1),NTT(b,1);
    	for(int i=0;i<N;i++) a[i]=a[i]*(ll)b[i]%ha;
    	NTT(a,-1);
    }
    
    int main(){
    	scanf("%d%lld",&n,&k);
    	for(int i=0;i<n;i++){
    		scanf("%d",a+i);
    	}
    	
    	solve();
    
    	for(int i=0;i<n;i++) printf("%d
    ",a[i]);
    	return 0;
    }
    

      

  • 相关阅读:
    Apache Shiro 使用手册(二)Shiro 认证
    jdk 环境变量
    IDEA 相关整理
    mysql 相关命令
    hbase 迁库移库步骤
    Linux 常用指令整理
    springboot aop + logback + 统一异常处理 打印日志
    查看jar包的jdk版本
    maven 将jar包推送到自己本机的maven库
    jar包内的文件导出的注意点
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8541390.html
Copyright © 2020-2023  润新知