• Luogu P4593 [TJOI2018]教科书般的亵渎


    亵渎终于离开标准了,然而铺场快攻也变少了

    给一个大力枚举(无任何性质)+艹出自然数幂和的方法,但是复杂度极限是(O(k^4))的,不过跑的好快233

    首先简单数学分析可以得出(k=m+1),因为每多一个空缺就会打断一张亵渎的连击

    那么我们考虑对于每个空缺求出答案,发现此时所求答案必定为一段自然数幂和并且减去空缺的数字幂

    发现数据范围(mle 50),那么我们直接暴力求出所有连续的段,然后大力枚举这一段开始最低的怪的血量

    空缺不妨暴力枚举,区间内的自然数幂和直接差分一下,那么我们只要能快速求出(S(n)=sum_{i=1}^n i^k)即可

    这里用了第二类斯特林数的推法,(S(n)=sum_{i=1}^n i^k=sum_{i=0}^n i^k)

    [=sum_{i=0}^nsum_{j=0}^k{ _j^k}i^{underline j} ]

    [=sum_{j=0}^k{ _j^k}sum_{i=0}^ni^{underline j} ]

    [=sum_{j=0}^k{ _j^k}j!sum_{i=0}^n C_i^j ]

    用归纳法,得(sum_{i=0}^n C_i^j=C_{n+1}^{j+1}),所以上式

    [=sum_{j=0}^k{ _j^k}j!C_{n+1}^{j+1} ]

    [=sum_{j=0}^k{ _j^k}frac{(n+1)^{underline{j+1}}}{j+1} ]

    所以我们预处理出组合数和第二类斯特林数,这部分就是(O(k^2))计算的

    因此总复杂度上界为(O(k^4)),实际在(O(k^3))左右(空缺不连续)

    CODE

    #include<cstdio>
    #include<map>
    #include<algorithm>
    #define RI register int
    #define CI const int&
    using namespace std;
    typedef long long LL;
    const int N=55,mod=1e9+7;
    int t,n,m,ans,cnt,pfx[N],s[N][N]; LL a[N],pos[N]; map <LL,int> ts;
    inline void inc(int& x,CI y)
    {
    	if ((x+=y)>=mod) x-=mod;
    }
    inline void dec(int& x,CI y)
    {
    	if ((x-=y)<0) x+=mod;
    }
    inline void Stirling_init(CI n)
    {
    	s[0][0]=1; for (RI i=1;i<=n;++i) for (RI j=1;j<=i;++j)
    	s[i][j]=s[i-1][j-1],inc(s[i][j],1LL*j*s[i-1][j]%mod);
    }
    inline int quick_pow(int x,int p=mod-2,int mul=1)
    {
    	for (;p;p>>=1,x=1LL*x*x%mod) if (p&1) mul=1LL*mul*x%mod; return mul;
    }
    inline int low_fact(const LL& x,CI t,int ret=1)
    {
    	for (RI i=1;i<=t;++i) ret=1LL*ret*(x-i+1)%mod; return ret;
    }
    inline int pow_sum(const LL& x,CI k,int ret=0)
    {
    	for (RI i=1;i<=k;++i) inc(ret,1LL*s[k][i]*low_fact(x+1,i+1)%mod*quick_pow(i+1)%mod); return ret;
    }
    inline int calc(CI x,const LL& y,CI k)
    {
    	int ret=pow_sum(y,k); dec(ret,pow_sum(x-1,k)); return ret;
    }
    inline int none_sum(CI st,const LL& lim,CI k,int ret=0)
    {
    	for (RI i=1;i<=m;++i) if (a[i]>=lim) inc(ret,quick_pow(st+a[i]-lim,k)); return ret;
    }
    int main()
    {
    	for (scanf("%d",&t);t;--t)
    	{
    		RI i,j; for (ts.clear(),scanf("%d%d",&n,&m),i=1;i<=m;++i) scanf("%lld",&a[i]),ts[a[i]]=1;
    		for (sort(a+1,a+m+1),pos[cnt=i=1]=pfx[1]=1;i<=m;++i) if (a[i]!=n)
    		if (ts.count(a[i]+1)) ts[a[i]+1]+=ts[a[i]]; else pos[++cnt]=a[i]+1,pfx[cnt]=ts[a[i]];
    		for (ans=0,Stirling_init(m+1),i=1;i<=cnt;++i) for (j=1;j<=pfx[i];++j)
    		inc(ans,calc(j,j+n-pos[i],m+1)),dec(ans,none_sum(j,pos[i],m+1)); printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    一次性能测试的面试问题
    一次APP测试的感悟
    《程序员跳槽全攻略》读书笔记
    如果有人让你推荐编程技术书,请叫他看这个列表
    上班的一天
    马士兵Java视频教程 —— 学习顺序
    月薪3万的技术网站资源收集
    给32岁的自己一些答案
    《Vuser虚拟用户开发》读书笔记
    shell脚本异常:/bin/sh^M:bad interpreter: No such file or directory
  • 原文地址:https://www.cnblogs.com/cjjsb/p/10945222.html
Copyright © 2020-2023  润新知