zoukankan      html  css  js  c++  java
  • [TJOI2018] 教科书般的亵渎

    前言

    亵渎不是都退了好久了吗,哦,是2018年的题啊,那没事了

    没DK我玩什么ss

    题目

    洛谷

    讲解

    其实这道题就是让你求(sum_{i=1}^n i^k)

    我们令(S(n,k)=sum_{i=1}^n i^k)

    我们来康康这个式子:

    [(n+1)^k-n^k=sum_{i=1}^k C_k^i*n^{k-i} ]

    然后我们可以列出共(n)个这样类似的式子:

    [n^k-(n-1)^k=sum_{i=1}^k C_k^i*(n-1)^{k-i} ]

    [(n-1)^k-(n-2)^k=sum_{i=1}^k C_k^i*(n-2)^{k-i} ]

    ...

    [2^k-1^k=sum_{i=1}^k C_k^i*1^{k-i} ]

    我们将这(n)个式子加起来康康会发生什么:

    [(n+1)^k-1=sum_{i=1}^{k}C_k^i*S(n,k-i) ]

    我们试图通过对式子变形来使得它出现(S(n,k))一项

    [(n+1)^{k+1}-1=sum_{i=1}^{k+1}C_{k+1}^{i}*S(n,k-i+1) ]

    [(n+1)^{k+1}-1=sum_{i=2}^{k+1}C_{k+1}^{i}*S(n,k-i+1)+C_{k+1}^1*S(n,k) ]

    [(n+1)^{k+1}-1=sum_{i=2}^{k+1}C_{k+1}^{i}*S(n,k-i+1)+(k+1)*S(n,k) ]

    出现目标!移项!

    [S(n,k)=frac{(n+1)^{k+1}-1-sum_{i=2}^{k+1}C_{k+1}^{i}*S(n,k-i+1)}{k+1} ]

    根据(C_n^m=C_n^{n-m})可推出:

    [S(n,k)=frac{(n+1)^{k+1}-1-sum_{i=0}^{k-1}C_{k+1}^{i}*S(n,i)}{k+1} ]

    (O(k^2))递推即可,其中边界为(S(n,0)=n)

    然而我们发现求(sum_{i=1}^n i^k)的时候中间可能有断掉的几个数

    但明显不会太多,暴力减掉即可

    代码

    void pre()
    {
    	C[0][0] = 1;
    	for(int i = 1;i < MAXM;++ i)
    	{
    		C[i][0] = 1;
    		for(int j = 1;j <= i;++ j) C[i][j] = (C[i-1][j] + C[i-1][j-1]) % MOD;
    	}
    }
    int qpow(LL x,int y)
    {
    	x %= MOD;
    	int ret = 1;
    	while(y){if(y & 1) ret = 1ll * ret * x % MOD;x = 1ll * x * x % MOD;y >>= 1;}
    	return ret;
    }
    int S(int x)
    {
    	if(!x) return now;
    	if(mem[x]) return mem[x];
    	int ret = qpow(now+1,x+1) - 1;
    	for(int i = 0;i < x;++ i) ret = (ret - 1ll * C[x+1][i] * S(i)) % MOD;
    	ret = (ret + MOD) % MOD;
    	ret = 1ll * ret * qpow(x+1,MOD-2) % MOD;
    	return mem[x] = ret;
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	pre();
    	for(int T = Read(); T ;-- T)
    	{
    		n = Read(); m = Read();
    		for(int i = 1;i <= m;++ i) a[i] = Read();
    		sort(a+1,a+m+1);
    		k = m+1; now = n;
    		int ans = 0;
    		for(int i = 1;i <= k;++ i)
    		{
    			for(int j = 0;j <= k;++ j) mem[j] = 0;
    			ans = (ans + S(k)) % MOD;
    			for(int j = i;j <= m;++ j) ans = (ans - qpow(a[j] - n + now,k) + MOD) % MOD;
    			now -= a[i] - a[i-1];
    		}
    		Put(ans,'
    ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    【转】使用Javascript改变HTML内容 拓荒者
    【转】ASP.NET MVC 过滤器Filter 拓荒者
    【转】JavaScript简介 拓荒者
    edge.js架起node.js和.net互操作桥梁
    利用Node.js为Node.js生成HttpStatusCode辅助类并发布到npm
    nodejs上HTML分析利器nodejquery
    JavaScript 函数replace揭秘
    利用Node.js本地构建
    Angularjs的IOC Inject分析
    团队文化中的害群之马
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/13669720.html
Copyright © 2011-2022 走看看