luoguP5495:Dirichlet 前缀和

梦想的初衷 提交于 2021-01-14 06:53:32

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

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

如果有这一维就加进去就可以了~神奇。

#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;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!