zoukankan      html  css  js  c++  java
  • 题解 「BZOJ2137」submultiple

    题目传送门

    题目大意

    给出 (M,k) ,求出

    [sum_{x|M}sigma(x)^k ]

    给出 (P_i),满足 (n=prod_{i=1}^{n}a_i^{P_i}),其中 (a_i) 是第 (i) 个质数。

    对于 (45\%) 的数据点满足 (kle 10^5),对于其余数据点满足 (kle 12)

    思路

    首先你发现答案就是:

    [prod_{i=1}^{n}(sum_{j=1}^{P_i+1}j^k) ]

    (因为约数个数是个积性函数)

    然后你发现对于 (45\%) 的数据点可以直接暴力,然后另外一部分可以直接拉格朗日插值法解决。

    ( exttt{Code})

    #include <bits/stdc++.h>
    using namespace std;
    
    #define Int register int
    #define mod 1000000007
    #define int long long
    #define MAXN 100005
    
    int n,k,P,pre[MAXN];
    
    int qkpow (int a,int b){
    	int res = 1;for (;b;b >>= 1,a = a * a % mod) if (b & 1) res = res * a % mod;
    	return res;
    }
    int inv (int x){return qkpow (x,mod - 2);}
    
    template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
    template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
    template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
    
    int Sum (int x){//计算sum_{i=1}^{x}i^k 
    	if (x <= k + 1) return pre[x];
    	int ans = 0;
    	for (Int i = 0;i <= k + 1;++ i){
    		int mot = 1,son = 1;
    		for (Int j = 0;j <= k + 1;++ j) 
    			if (i != j) mot = mot * (i + mod - j) % mod,son = son * (x + mod - j) % mod;
    		ans = (ans + pre[i] * son % mod * inv (mot) % mod) % mod;
    		ans = (ans % mod + mod) % mod;
    	}
    	return ans;
    }
    
    signed main(){
    	read (n,k),k %= (mod - 1);
    	if (k <= 12){//使用拉格朗日插值 
    		pre[0] = qkpow (0,k);
    		for (Int i = 1;i <= k + 1;++ i) pre[i] = (pre[i - 1] + qkpow (i,k)) % mod;
    		int res = 1;for (Int i = 1;i <= n;++ i) read (P),P %= mod,res = res * Sum (P + 1) % mod;
    		write (res),putchar ('
    ');
    		return 0;
    	}
    	int ans = 1;
    	pre[0] = qkpow (0,k);for (Int i = 1;i <= MAXN - 4;++ i) pre[i] = (pre[i - 1] + qkpow (i,k)) % mod;
    	for (Int i = 1;i <= n;++ i) read (P),P %= mod,ans = 1ll * ans * pre[P + 1] % mod;
    	write (ans),putchar ('
    ');
    	return 0;
    }
    
  • 相关阅读:
    flask_第一个程序
    Web框架_MVC vs MVT
    python_使用qrcode生成二维码
    HDU 4641
    SPOJ NSUBSTR
    SPOJ LCS2 多个串的最长公共子串
    SPOJ LCS 后缀自动机找最大公共子串
    POJ 1509 循环同构的最小表示法
    HDU 4821 字符串hash
    SPOJ GSS1 静态区间求解最大子段和
  • 原文地址:https://www.cnblogs.com/Dark-Romance/p/13648787.html
Copyright © 2011-2022 走看看