luoguP5495:Dirichlet 前缀和

题意:给定数组a[]的生成方式,而后b[i]=∑a[j]  ,(i%j==0),求全部b[i]的异或和。全部运算%2^32;c++

思路:高维前缀和的思想,先筛出全部素数,而后把每一个素数当成一维,那么分开考虑便可。复杂度O(NloglogN);数组

若是有这一维就加进去就能够了~神奇。ui

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std; const int maxn=20000010; #define uint unsigned int
uint seed; inline uint getnext(){ seed^=seed<<13; seed^=seed>>17; seed^=seed<<5; return seed; } uint a[maxn],ans; bool vis[maxn];int p[maxn/10],cnt,N; void solve() { rep(i,2,N){ if(!vis[i]) p[++cnt]=i; for(int j=1;j<=cnt&&i*p[j]<=N;j++){ vis[i*p[j]]=1; if(i%p[j]==0) break; } } rep(i,1,cnt) for(int j=2;p[i]*j<=N;j++) a[p[i]*j]+=a[j]; ans=a[1]; rep(i,2,N) ans^=(a[i]+a[1]); } int main() { cin>>N>>seed; rep(i,1,N) a[i]=getnext(); solve(); cout<<ans<<endl; return 0; }
相关文章
相关标签/搜索