[BZOJ3560] DZY Loves Math V

13 篇文章 0 订阅
本文介绍了一种利用质因数分解和快速幂优化技术解决特定数学问题的方法。通过对每个质因子单独考虑其贡献,并使用快速幂进行优化,最终通过乘积得到总贡献值。文章提供了一个C++实现示例,展示了如何有效地处理大规模数据。
摘要由CSDN通过智能技术生成

传送门
啊终于有一道我会自己做的啦ヾ(◍°∇°◍)ノ゙

发现可以对每个质因子分别考虑贡献,最后乘起来。
对于一个质因子 p p p ,设它在 i i i 个数里出现了 a i a_i ai 次,令 s u m = ∏ ( 1 + p 1 + p 2 + ⋯ + p a i ) sum=\prod (1+p^1+p^2+ \cdots +p^{a_i}) sum=(1+p1+p2++pai)
那么它的贡献就是 ( s u m − 1 ) ⋅ p − 1 p + 1 (sum-1) \cdot \dfrac{p-1}{p}+1 (sum1)pp1+1

然后很有信仰地暴力分解一波质因子就过了呢ヾ(✿゚▽゚)ノ

#include<bits/stdc++.h>
#include<tr1/unordered_map>
#define LL long long
#define re register
#define fr(i,x,y) for(re int i=(x);i<=(y);i++)
#define rf(i,x,y) for(int i=(x);i>=(y);i--)
#define frl(i,x,y) for(int i=(x);i<(y);i++)
using namespace std;
using namespace tr1;
const int N=10000006;
const int INF=2147483647;
const int p=1e9+7;
int n;
LL s[N];

void read(int &x){
	char ch=getchar();x=0;
	for(;ch<'0'||ch>'9';ch=getchar());
	for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+ch-'0';
}

inline void Add(LL &x,LL y){
	x+=y;
	while(x<0) x+=p;
	while(x>=p) x-=p;
}

LL qpow(LL a,int n){
	LL ans=1;
	for(LL sum=a;n;n>>=1,sum=sum*sum%p) if (n&1) ans=ans*sum%p;
	return ans;
}

int main(){
	read(n);
	int x;
	fr(i,1,n){
		read(x);
		for(int j=2;j*j<=x;j++)
		 if (x%j==0){
		 	LL cnt=1,xx=1;
		 	while(x%j==0) x/=j,xx=xx*j%p,Add(cnt,xx);
		 	if (!s[j]) s[j]=cnt;
		 	 else s[j]=s[j]*cnt%p;
		 }
		if (x){
			if (!s[x]) s[x]=x+1;
			 else s[x]=s[x]*(x+1)%p;
		}
	}
	LL ans=1;
	frl(i,1,N)
	 if (s[i]){
	 	LL sum=(s[i]-1)*(i-1)%p;
	 	sum=sum*qpow(i,p-2)%p;
	 	ans=ans*(sum+1)%p;
	 }
	cout<<ans<<endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值