对于这道题当然就是O(nlogn)的做法最简单了,只要枚举每个i的倍数加上Ai就好了。但是显然,n到了2e7的话就没有办法了喵
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef __int128 i128;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int MOD = 1e9 + 7;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 10;
#define int long long
void solve()
{
int n,a1,m;
cin>>n>>a1>>m;
vector<int> a(n + 1);
a[1] = a1;
for (int i = 2 ; i <= n ; i++)
{
a[i] = (a[i - 1] + 7 * i) % m;
}
vector<int> b(n + 1);
for (int i = 1 ; i <= n ; i++)
{
for (int j = i ; j <= n ; j += i)
{
b[j]+=a[i];
}
}
int ans = 0;
for (int i = 1 ; i <= n ; i++) ans ^= b[i];
cout<<ans<<'\n';
return;
}
signed main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int _ = 1;
//std::cin>>_;
while (_--)
{
solve();
}
return 0;
}
/*
∧_∧
(。•́︿•̀。)
/づ正数与负数
都要开心计算哦
*/
所以还有一个O(nloglogn)的方法,叫做迪利克雷前缀和,代码很简短喵
// A[] 数组一开始存的是初始值
// N 是我们要计算的最大范围
for (int p : primes) { // 1. 枚举每一个质数 p
if (p > N) break;
// 2. 从小到大枚举,把当前数 i 的值,加给它的 p 倍 (i * p)
for (int i = 1; i * p <= N; ++i) {
A[i * p] += A[i];
}
}
//循环结束之后A里面存的就是B了
具体为什么,我现在还没理解喵,所以不太能做详细的解释了喵

京公网安备 11010502036488号