牛客小白赛14 G.many sum

题目链接

题目描述

定义序列 A :

A 1 = A_1= A1=输入的东西

A i = ( A i − 1 + 7 ∗ i ) A_i=(A_i−1+7∗i) Ai=(Ai1+7i)% M M M, i ≥ 2 i \geq 2 i2

定义序列 B: B i B_i Bi= ∑ d ∣ i A d \sum_{d|i}A_d diAd

你要求 ⨁ i = 1 N \bigoplus_{i=1}^N i=1N B i B_i Bi

这样我们只要输入三个数,输出一个数啦~

其中 ⨁ \bigoplus 表示异或,也就是说你需要把所有的 B i B_i Bi 异或起来输出

输入描述

第一行输入三个整数 N , A 1 , M N,A_1,M N,A1,M

输出描述

第一行一个整数,表示答案

示例1
输入
10 10 313
输出
441
备注
1 ≤ N ≤ 2 ∗ 1 0 6 , 0 ≤ A i , M &lt; 1 0 4 1\leq N \leq 2*10^6,0 \leq A_i,M &lt;10^4 1N2106,0Ai,M<104
题目大意

题目的大意题干已经描述的很清楚了,但最关键的部分就是求出数组 B B B的值(其中 ∑ d ∣ i \sum_{d|i} di表示 i i i的所有因子求和),然后取数组 B B B所有元素的异或即可。

解题思路

在求数组 B B B的时候,可以很自然的联想到埃氏筛素数的方法,对于每一个数 a a a,以这个数为起点,遍历它的所有倍数,它的所有倍数都应该加上数 a a a,时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)

AC代码
#include <bits/stdc++.h>
const int Max_N=2e6+10;
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
int a[Max_N],b[Max_N];
int main(int argc, char const *argv[])
{
	int n,a1,m;
	cin>>n>>a1>>m;
	a[1]=a1;
	for(int i=2;i<=n;i++)
	{
		a[i]=(a[i-1]+7*i)%m;
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=i;j<=n;j+=i)
			b[j]+=a[i];
	}
	int res=0;
	for(int i=1;i<=n;i++)
	{
		res^=b[i];
	}
	cout<<res<<endl;
	return 0;
}
总结

第一次遇到 B i B_i Bi= ∑ d ∣ i A d \sum_{d|i}A_d diAd这个式子,不明白这个式子表达的意思,问了群友之后说表达的是 i i i% d d d = 0 0 0,但我还是在写代码的过程中写错了,理解成 d d d % i i i= 0 0 0。所以最后弄死过不了样例, d e b u g debug debug好久都没有找到原因。最后题解出来了才发现自己把题意给理解错了。

菜是原罪
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值