• 【模板】杜教筛(Sum)


    传送门

    Description

    给定一个正整数(N(Nle2^{31}-1))

    [ans1=sum_{i=1}^n varphi(i) ]

    [ans_2=sum_{i=1}^n mu(i) ]

    Solution

    总算是写了一个不会(TLE)的杜教筛,不想用(map),因此上了一个很丑的(Hash)……


    Code

    #include<bits/stdc++.h>
    #define ll long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return x*f;
    }
    #define MN 1900000
    int cnt,pr[MN];
    bool mark[MN];
    struct Node{int id;ll phi,mu;}MI[MN];
    inline void init()
    {
        register int i,j;
        for(i=1;i<MN;++i) MI[i].id=i;
        MI[1].phi=MI[1].mu=1;
        for(i=2;i<MN;++i)
        {
            if(!mark[i]){pr[++cnt]=i;MI[i].phi=i-1;MI[i].mu=-1;}
            for(j=1;j<=cnt&&i*pr[j]<MN;++j)
            {
                #define now i*pr[j]
                mark[now]=true;
                if(i%pr[j]==0){MI[now].mu=0;MI[now].phi=MI[i].phi*pr[j];break;}
                else MI[now].mu=-MI[i].mu,MI[now].phi=MI[i].phi*(pr[j]-1);
                #undef now
            }
        }
        for(i=1;i<MN;++i) MI[i].phi+=MI[i-1].phi,MI[i].mu+=MI[i-1].mu;
    }
    class Hash
    {
        #define mod 23333
        private:
            std::vector<Node> a[mod];
            int ha,i;
            Node em;
        public:
            Hash(){em=(Node){0,0ll,0ll};};
            inline void insert(int id,ll phi,ll mu){a[id%mod].push_back((Node){id,phi,mu});}
            inline Node find(int id)
            {
                ha=id%mod;
                for(i=a[ha].size()-1;~i;--i) if(a[ha][i].id==id) return a[ha][i];
                return em;
            }
    }HA;
    inline Node calc(int n)
    {
        if(n<MN) return MI[n];
        register Node ans,tmp;
        if((ans=HA.find(n)).id) return ans;
        ll ret1=1ll,ret2=1ll*n*(n+1)/2ll;
        for(register ll i=2,j;i<=n;i=j+1)
            j=n/(n/i),tmp=calc(n/i),ret1-=(j-i+1)*tmp.mu,ret2-=(j-i+1)*tmp.phi;
        ans=(Node){n,ret2,ret1};HA.insert(n,ret2,ret1);
        return ans;
    }
    int main()
    {
        init();
        register int T,n;
        T=read();
        register Node ans;
        while(T--)
        {
            n=read();
            ans=calc(n);
            printf("%lld %lld
    ",ans.phi,ans.mu);
        }
        return 0;
    }
    


    Blog来自PaperCloud,未经允许,请勿转载,TKS!

  • 相关阅读:
    macOS下查看端口是否被占用命令
    macOS下安装tomcat服务器
    unittest 知识问答题-也许面试会有用-欢迎补充
    python.unittest中常用断言方法
    如何在命令行terminal中运行pycharm项目
    如何保证 软件测试覆盖率
    如何衡量 测试覆盖率
    软件测试全流程 总结
    接口测试对传统测试模型的改进
    关于http/https协议
  • 原文地址:https://www.cnblogs.com/PaperCloud/p/10242121.html
Copyright © 2020-2023  润新知