求前n项平方数的和模板

忽明忽暗
走廊里有 n 盏灯,编号依次为 1,2,3,…,n,由学校电路控制中心管理。初始时,所有灯都是关闭的。某黑客入侵了学校电路控制中心,黑客想让灯忽明忽暗,进行了 n 轮操作。第 i 轮操作,会让所有编号为 i 的倍数的灯状态反转,也就是打开的变为关闭,关闭的变为打开。现在黑客想知道,n 轮操作后,所有亮着的灯的编号之和为多少。因为答案很大,只需输出答案对 10^9+7 取模的结果。

思路:模拟一下可以发现最后只有完全平方数的灯是亮的,因为只有完全平方数的因子是奇数个,所以该题就是求前 sqrt(n)项平方数和。

前 n 项平方数的和 公式为: ans = n * (n + 1 ) * (2 * n + 1 ) / 6
由于 ans 很大 且 a / b % c != a % c / b % c ,所以除以6 我们分解为 2 * 3 , n * ( n + 1 ) 一定是偶数, 再判断 n * ( n + 1 ) 是否为 3 的倍数 , 如果不是,那么 n 和 n + 1 均不是 3 的倍数 那么 n % 3 == 1,如果 n % 3 == 1 的话 那么 2 * n + 1 一定是被 3 整除的。
综上可得:

	if( n * (n + 1) % 3 == 0)
	{
		sum = n * (n + 1) / 6 % mod * (2 * n + 1) % mod;
	}
	else
	{
		sum = n * (n + 1) / 2 % mod * (2 * n + 1 ) / 3 % mod;
	}

代码:

#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
int main()
{
    long long n;
    cin >> n;
    long long  m = sqrt(n);
    long long  ans = m * (m + 1) / 2;
    if(ans % 3 == 0)
    {
     ans = ans / 3 % mod * (2 * m + 1) % mod;
    }
    else
    {
        ans = ans % mod * (2 * m + 1) / 3 % mod ;
    }
    cout << ans << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值