题目描述
定义序列 A :
A 1 = A_1= A1=输入的东西
A i = ( A i − 1 + 7 ∗ i ) A_i=(A_i−1+7∗i) Ai=(Ai−1+7∗i)% M M M, i ≥ 2 i \geq 2 i≥2
定义序列 B: B i B_i Bi= ∑ d ∣ i A d \sum_{d|i}A_d ∑d∣iAd
你要求 ⨁ 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 < 1 0 4 1\leq N \leq 2*10^6,0 \leq A_i,M <10^4 1≤N≤2∗106,0≤Ai,M<104 |
题目大意
题目的大意题干已经描述的很清楚了,但最关键的部分就是求出数组 B B B的值(其中 ∑ d ∣ i \sum_{d|i} ∑d∣i表示 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 ∑d∣iAd这个式子,不明白这个式子表达的意思,问了群友之后说表达的是 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好久都没有找到原因。最后题解出来了才发现自己把题意给理解错了。