zoukankan      html  css  js  c++  java
  • 洛谷5495:Dirichlet前缀和

    洛谷5495:Dirichlet前缀和

    题目描述:

    给定一个长度为(n)的数列(a_1,a_2,a_3,...,a_n)

    现在要求出一个长度为(n)的序列(b_1,b_2,b_3,...,b_n),满足:

    [b_k=sum_{i|k}a_i ]

    输出所有(b)的异或和。

    数据范围(:nleq 10^7)

    思路:

    倍数法时间复杂度大约在(O(nlnn))

    for(uint i = 1; i <= n; i++)
            a[i] = getnext();
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n/i; j++)
            b[i*j] += a[i];
    

    结果是10个测试点T了9个。

    根据算术基本定理,一个数可以被唯一的分解成几个质数相乘。

    一个数(x)如果是另一个数(y)的约数。

    那么(x)分解之后的质数和指数都是(y)的”子集“。

    对于一个数,用预处理好的质数去处理它的贡献。

    时间复杂度(:O(nloglogn))

    #include<bits/stdc++.h>
    #define uint unsigned int
    using namespace std;
    const int maxn = 2e7 + 10;
    uint seed;
    inline uint getnext()
    {
        seed ^= seed<<13;
        seed ^= seed>>17;
        seed ^= seed<<5;
        return seed;
    }
    
    int primes[maxn], cnt;
    bool vis[maxn];
    void init(int n)
    {
        for(int i = 2; i <= n; i++)
        {
            if(!vis[i]) primes[++cnt] = i;
            for(int j = 1; primes[j] <= n/i; j++)
            {
                vis[i*primes[j]] = 1;
                if(i % primes[j] == 0) break;
            }
        }
    }
    
    uint a[maxn], b[maxn], ans;
    
    int main()
    {
        init(maxn-5);
        uint n;
        cin >> n >> seed;
        for(uint i = 1; i <= n; i++)
        {
            a[i] = getnext();
            b[i] = a[i];
        }
        for(int i = 1; i <= cnt; i++)
            for(int j = 1; primes[i] <= n/j; j++)
                b[j*primes[i]] += b[j];
        for(int i = 1; i <= n; i++)
            ans ^= b[i];
        cout << ans << endl;
        return 0;
    }
    
    
  • 相关阅读:
    给统计人讲python(3)模拟城市_数据分析
    非均匀时间序列按固定时间间隔求和
    随机训练样本的方法
    df.empty判断空df,timestamp推算n秒前的时间
    优雅地循环字典键值
    panel的dropna方法
    给统计人讲Python(4)_股票数据处理
    给统计人讲Python(2)_Pandas入门
    给统计人讲Python(1)_科学计算库-Numpy
    生成不重复随机数
  • 原文地址:https://www.cnblogs.com/zxytxdy/p/12271871.html
Copyright © 2011-2022 走看看