zoukankan      html  css  js  c++  java
  • LOJ 6261 一个人的高三楼

    LINK:一个人的高三楼

    求一个数列的K次前缀和。

    (nleq 100000,kleq 2^{60})

    前缀和K次。这类似于多项式卷积。

    构造 普通型生成函数F(x)表示数列中的每一项 0次前缀和(F(x)=sum_{i=0}^{n-1}a_{i+1}x^i)

    考虑如何生成1次前缀和 构造多项式G(x).

    使得 (F(x)[0] * G(x)=F(x)[1])

    可以比较显然的得到(G(x)=sum_{i=0}^{n-1}x^i)

    所以所求为(F(x)*(G(x))^k.)

    多项式快速幂 复杂度nlognlogk.常数过大过不了。

    由于G(x)这个多项式的系数的特殊性 考虑O(1)求出(G(x)^k)的各项系数。

    我们只要前n-1项 对于第i项的系数 有K个多项式的某项系数提供 可以写成 (sum_{i=1}{k}w_i=i)

    显然是隔板法 系数为C(i+k-1,k-1)=C(i+k-1,i).

    直接求不太好求 但是 这些系数是递增的 如C(i+k-1,i),C(i+1+k-1,i+1),C(i+2+k-1,i+2)...

    第一项好求为1 第二项可以由第一项推出来。

    所以总复杂度 nlogn.

    //#include<bitsstdc++.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 get(x) x=read()
    #define gt(x) scanf("%d",&x)
    #define put(x) printf("%d
    ",x)
    #define putl(x) printf("%lld
    ",x)
    #define gc(a) scanf("%s",a+1)
    #define rep(p,n,i) for(RE ll i=p;i<=n;++i)
    #define go(x) for(ll i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
    #define fep(n,p,i) for(RE ll i=n;i>=p;--i)
    #define pii pair<ll,ll> 
    #define mk make_pair
    #define mod 998244353
    #define RE register
    #define gf(x) scanf("%lf",&x)
    #define pf(x) ((x)*(x))
    #define ull unsigned long long
    #define P 1000000000000000ll
    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 ll read()
    {
    	RE ll x=0,f=1;char ch=getc();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
    	return x*f;
    }
    const ll MAXN=300010,G=3;
    ll n,k,lim;
    ll a[MAXN],b[MAXN],rev[MAXN];
    ll ksm(ll b,ll p)
    {
    	b=b%mod;ll cnt=1;
    	while(p)
    	{
    		if(p&1)cnt=cnt*b%mod;
    		b=b*b%mod;p=p>>1;
    	}
    	return cnt;
    }
    inline void NTT(ll *a,ll op)
    {
    	rep(0,lim-1,i)if(rev[i]<i)swap(a[i],a[rev[i]]);
    	for(ll len=2;len<=lim;len=len<<1)
    	{
    		ll mid=len>>1;
    		ll wn=ksm(G,op==1?(mod-1)/len:mod-1-(mod-1)/len);
    		for(ll j=0;j<lim;j+=len)
    		{
    			ll d=1;
    			for(ll i=0;i<mid;++i)
    			{
    				ll x=a[i+j],y=a[i+j+mid]*d%mod;
    				a[i+j]=(x+y)%mod;a[i+j+mid]=(x-y+mod)%mod;
    				d=d*wn%mod;
    			}
    		}
    	}
    	if(op==-1)
    	{
    		ll inv=ksm(lim,mod-2);
    		rep(0,lim-1,i)a[i]=a[i]*inv%mod;
    	}
    }
    signed main()
    {
    	freopen("1.in","r",stdin);
    	get(n);get(k);b[0]=1;
    	rep(0,n-1,i)get(a[i]);
    	if(!k){rep(0,n-1,i)putl(a[i]);return 0;}
    	rep(1,n-1,i)b[i]=(b[i-1]+b[i-1]*ksm(i,mod-2)%mod*((k-1)%mod)%mod)%mod;
    	//b[i]=C(i+k-1,i)=C(i+k-2,i-1)+C(i+k-2,i);
    	lim=1;while(lim<n+n)lim=lim<<1;
    	rep(1,lim-1,i)rev[i]=rev[i>>1]>>1|((i&1)?lim>>1:0);
    	NTT(a,1);NTT(b,1);
    	rep(0,lim-1,i)a[i]=a[i]*b[i]%mod;
    	NTT(a,-1);
    	rep(0,n-1,i)putl(a[i]);
    	return 0;
    }
    

    NTT好久没打了 所以调了1h.

  • 相关阅读:
    sql server中case when的用法
    Memcached Cache
    查询表、字段、类型、是否主键、长度、小数位、是否允许空、默认值等详细查询
    标准北京时间同步
    删除表中重复id值
    使用canvas压缩图片 并上传
    使用LogParser 将iis日志导入到数据库中
    查询表大小和行数
    sqlserver快速删除整个表数据
    Slim安装以及使用【转】
  • 原文地址:https://www.cnblogs.com/chdy/p/12622403.html
Copyright © 2011-2022 走看看