jzoj5025. 【NOI2017模拟3.19】Sum

Description

jzoj5025. 【NOI2017模拟3.19】Sum_第1张图片

Sample Input

输入1:
23

输入2:
77685

Sample Output

输出1:
18690

输出2:
1200366582

Data Constraint

jzoj5025. 【NOI2017模拟3.19】Sum_第2张图片

赛时

这多久以前了。
好像才两天前……
反正比赛时看到lcm,看到gcd就以为是什么神奇的莫比乌斯函数。
虾鸡儿乱搞,发现我还是不能把里面的gcd给挖出来。
然后再大力尝试改变枚举位置,反正最后划出来的式子奇丑无比。
然鹅我还天真地以为数据是根号级别的。
其实是min25版题(并不)
太菜了。

题解

吭哧吭哧一天终于再次搞懂了min25,然后吭哧吭哧一天终于把这道题的毒瘤式子推出来了。
在这里插入图片描述
心力憔悴

首先回顾min25的几个要点,首先是积性函数
这个东东直接感受一下就好了,毕竟不是完全积性函数,然后又是求gcd,所以直接相乘并不会多出些奇怪的东东。

其次是 f ( p q ) f(p^q) f(pq)能快速求,且 f ( p ) f(p) f(p)能表示成多项式或几个完全积性函数的积。
这个东东并不显然,我们直接推柿子。

引理:

先有一个引理,之后会用到:
l c m ( g c d ( a , b ) , g c d ( a , c ) ) = g c d ( a , l c m ( b , c ) ) lcm(gcd(a,b),gcd(a,c))=gcd(a,lcm(b,c)) lcm(gcd(a,b),gcd(a,c))=gcd(a,lcm(b,c))
引理证明:
考虑gcd和lcm的意义是什么。我们发现,对于任意两个数a,b分解质因数,那么他们之间的gcd和lcm即为质因数指数求min和求max。
那么上柿子我们就变为:
m a x ( m i n ( a ′ , b ′ ) , m i n ( a ′ , c ′ ) ) = m i n ( a ′ , m a x ( b ′ , c ′ ) ) max(min(a',b'),min(a',c'))=min(a',max(b',c')) max(min(a,b),min(a,c))=min(a,max(b,c))
其中 a ′ , b ′ , c ′ a',b',c' a,b,c意义是分解质因数后 a , b , c a,b,c a,b,c同一个质数的指数是多少。
然后这个东东分类讨论即可知道他是对的。
当然,换成另一个形式也是正确的:
g c d ( l c m ( a , b ) , l c m ( a , c ) ) = l c m ( a , g c d ( b , c ) ) gcd(lcm(a,b),lcm(a,c))=lcm(a,gcd(b,c)) gcd(lcm(a,b),lcm(a,c))=lcm(a,gcd(b,c))

柿子证明

现在正式开始推柿子。
∑ i = 1 n ∑ j = 1 i ∑ k = 1 i l c m ( g c d ( i , j ) , g c d ( i , k ) ) \sum_{i=1}^n\sum_{j=1}^i\sum_{k=1}^ilcm(gcd(i,j),gcd(i,k)) i=1nj=1ik=1ilcm(gcd(i,j),gcd(i,k))
我们用一个函数替换后面的东东:
∑ i = 1 n f ( i ) , f ( x ) = ∑ j = 1 x ∑ k = 1 x l c m ( g c d ( x , j ) , g c d ( x , k ) ) \sum_{i=1}^nf(i),f(x)=\sum_{j=1}^x\sum_{k=1}^xlcm(gcd(x,j),gcd(x,k)) i=1nf(i),f(x)=j=1xk=1xlcm(gcd(x,j),gcd(x,k))
现在问题变为求f。
f ( p q ) = ∑ j = 1 p q ∑ k = 1 p q l c m ( g c d ( p q , j ) , g c d ( p q , k ) ) f(p^q)=\sum_{j=1}^{p^q}\sum_{k=1}^{p^q}lcm(gcd(p^q,j),gcd(p^q,k)) f(pq)=j=1pqk=1pqlcm(gcd(pq,j),gcd(pq,k))
= ∑ i = 0 q p i ∑ j = 1 p q ∑ k = 1 p q [ l c m ( g c d ( p q , j ) , g c d ( p q , k ) ) = p i ] =\sum_{i=0}^qp^i\sum_{j=1}^{p^q}\sum_{k=1}^{p^q}[lcm(gcd(p^q,j),gcd(p^q,k))=p^i] =i=0qpij=1pqk=1pq[lcm(gcd(pq,j),gcd(pq,k))=pi]
= ∑ i = 0 q p i ∑ j = 1 p q ∑ k = 1 p q [ g c d ( p q , l c m ( j , k ) ) = p i ] =\sum_{i=0}^qp^i\sum_{j=1}^{p^q}\sum_{k=1}^{p^q}[gcd(p^q,lcm(j,k))=p^i] =i=0qpij=1pqk=1pq[gcd(pq,lcm(j,k))=pi]
已知,c>q,那么可以从gcd的意义上知道,柿子可以拆成这样:
= ∑ i = 0 q p i ∑ j = 1 p q ∑ k = 1 p q [ l c m ( j , k ) = s ∗ p i 且 s ! ∣ p ( 不 整 除 ) ] =\sum_{i=0}^qp^i\sum_{j=1}^{p^q}\sum_{k=1}^{p^q}[lcm(j,k)=s*p^i且s !| p(不整除)] =i=0qpij=1pqk=1pq[lcm(j,k)=spis!p()]
然后这样还是很难直接推,于是继续从意义下手。
首先,右边的 s p i sp^i spi(sp杂化现象) 可以拆成两部分,一个是 s s s,一个是 p i p^i pi,所以我们分开贡献算。我们考虑 j j j的贡献为 p x ∗ s 1 p^x*s1 pxs1 k k k的贡献为 p y ∗ s 2 p^y*s2 pys2。那么我们可以知道,那个s我们可以直接用欧拉函数来表示,然后再注意一下边界即可得到下面柿子:
φ ( p q − i ) 2 + 2 ∗ ∑ x = 0 i − 1 φ ( p q − x ) ∗ φ ( p q − i ) \varphi (p^{q-i})^2+2*\sum_{x=0}^{i-1}\varphi (p^{q-x})*\varphi (p^{q-i}) φ(pqi)2+2x=0i1φ(pqx)φ(pqi)

然后再利用等比数列和欧拉函数的性质,大力地花费多张草稿纸和理智和心智,即可将这个丑陋的式子拆掉。
(mdzz推了我两次错的,正负号看得昏头)
在这里插入图片描述
所以我们终于得到一个非常好康的式子:
f ( p q ) = ( 2 q + 1 ) ∗ ( p 2 q − p 2 q − 1 ) + p q − 1 f(p^q)=(2q+1)*(p^{2q}-p^{2q-1})+p^{q-1} f(pq)=(2q+1)(p2qp2q1)+pq1
所以我们就满足min25的几个条件了。

切吧!

代码

注意着玩意还要自然溢出,帮pascal选手 (话说还有这玩意儿吗) QWQ。

#include 
#include 
#include 
#include 
using namespace std;
const unsigned long long mo=4294967296;
const int maxn=1000010;

unsigned long long zs[maxn],n,m,d[maxn],sum[maxn],sum1[maxn],id,wz1,wz2,id1[maxn],id2[maxn],g2[maxn],g1[maxn],g0[maxn],nex,now;
int tot;
bool bz[maxn];

unsigned long long qsm(unsigned long long a,unsigned long long b)
{
	unsigned long long t=1;
	unsigned long long y=a;
	while (b>0)
	{
		if ((b&1)==1) t=t*y%mo;
		y=y*y%mo;
		b/=2;
	}
	return t;
}

void getg()
{
	for (int i=1;i<=zs[0];i++)
	{
		for (int j=1;j<=tot;j++)
		{
			if (zs[i]*zs[i]<=d[j])
			{
				id=d[j]/zs[i];
				if (id<=m) wz1=id1[id];else wz1=id2[n/id];
				id=zs[i]-1;
				if (id<=m) wz2=id1[id];else wz2=id2[n/id];
				
				g2[j]=(g2[j]-zs[i]*zs[i]%mo*(g2[wz1]-sum1[i-1]+mo)%mo+mo)%mo;
				g1[j]=(g1[j]-zs[i]%mo*((g1[wz1]-sum[i-1]+mo)%mo)%mo+mo)%mo;
				g0[j]=(g0[j]-(g0[wz1]-(i-1))%mo+mo)%mo;
			}
			else
			{
				break;
			}
		}
	}
}

long long js(long long p,long long q)
{
	unsigned long long a=(q*2%mo+1)%mo;
	unsigned long long b=(qsm(p,2*q)-qsm(p,2*q-1)+mo)%mo;
	unsigned long long c=(qsm(p,q-1))%mo;
	return (a*b%mo+c)%mo;
}

unsigned long long gets(unsigned long long a,int b)
{
	if (a==0 || zs[b]>a) return 0;
//	printf("%lld\n",a);
	unsigned long long id=a,wz1,wz2;
	if (id<=m) wz1=id1[id]; else wz1=id2[n/id];
	
	long long ss=0;
	ss=((3*g2[wz1]%mo-3*g1[wz1]%mo+g0[wz1]+mo)%mo-(3*sum1[b-1]%mo-3*sum[b-1]%mo+(b-1)+mo)%mo+mo)%mo;
	
	for (int i=b;i<=zs[0];i++)
	{
		if (zs[i]*zs[i]<=a)
		{
			unsigned long long mi=zs[i];
			if (zs[i]*zs[i]>a) continue;
			for (int e=1;mi*zs[i]<=a;e++,mi=mi*zs[i])
			{
				unsigned long long kk1=js(zs[i],e);
				unsigned long long kk2=js(zs[i],e+1);
				ss=(ss+kk1*gets(a/mi,i+1)%mo+kk2%mo)%mo;
			}
		}
		else break;
	}
	return ss;
}

int main()
{
	freopen("data.in","r",stdin);
//	freopen("sum.in","r",stdin);
//	freopen("sum.out","w",stdout);
	for (int i=2;i<=100000;i++)
	{
		if (!bz[i])
		{
			zs[0]++;
			zs[zs[0]]=i;
			for (int j=1;j<=100000/i;j++)
			{
				bz[j*i]=true;
			}
		}
	}
	
	for (int i=1;i<=zs[0];i++)
	{
		sum[i]=(sum[i-1]+zs[i]%mo)%mo;
		sum1[i]=(sum1[i-1]+zs[i]*zs[i]%mo)%mo;
	}
	
	scanf("%lld",&n);
	if (n==1)
	{
		printf("1\n");
		return 0;
	}
	
	m=sqrt(n);
	for (long long i=1;i<=n;i=nex+1)
	{
		if (i>100000)
		{
			int j=0;
		}
		nex=n/(n/i);
		d[++tot]=n/i;
		now=(n/i);
		unsigned long long op1=now;
		unsigned long long op2=now+1;
		unsigned long long op3=2*now+1;
		if (op1%2==0) op1/=2;
		else if (op2%2==0) op2/=2;
		else if (op3%2==0) op3/=2;
		if (op1%3==0) op1/=3;
		else if (op2%3==0) op2/=3;
		else if (op3%3==0) op3/=3;
		g2[tot]=(op1%mo*op2%mo*op3%mo+mo-1)%mo;
		op1=now;
		op2=now+1;
		if (op1%2==0) op1/=2;
		else if (op2%2==0) op2/=2;
		g1[tot]=(op1%mo*op2%mo-1+mo)%mo;
		g0[tot]=(now-1+mo)%mo;
		if (d[tot]<=m) id1[n/i]=tot;
		else id2[n/(n/i)]=tot;
	}
	
	getg();
	
	unsigned long long ans=gets(n,1);
	printf("%u\n",(ans+1)%mo);
}

你可能感兴趣的:(数学杂论)