• bzoj3944:Sum


    传送门

    杜教筛板子题

    又是卡了一晚上的常数

    我的hash实现能力似乎差了点,写出来的hash连map都不如

    用了点奇技淫巧,拿unordered_map把这题A了

    先考虑(ans2)

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

    看到(mu)就想到了(mu*I=ε)

    然后由杜教筛的式子可以得((S(n))(sum_{i=1}^{n}mu(i))

    [S(n)I(1)=sum_{i=1}^{n}ε(i)-sum_{d=2}^{n}I(d)S(lfloor frac{n}{d} floor)\ S(n)=1-sum_{d=2}^{n}S(lfloor frac{n}{d} floor)\ ]

    然后考虑(ans1)

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

    由于(sum_{d|n}phi(d)=n)

    所以可得(phi*I=id)

    同上设(S(n)=sum_{i=1}^{n}phi(i))

    [S(n)I(1)=sum_{i=1}^{n}id(i)-sum_{d=2}^{n}I(d)S(lfloor frac{n}{d} floor)\ S(n)=(n+1)*n/2-sum_{d=2}^{n}S(lfloor frac{n}{d} floor) ]

    递归分块就好了

    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<tr1/unordered_map>
    using namespace std;
    void read(int &x) {
        char ch; bool ok;
        for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
        for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
    }
    #define rg register
    const int maxn=4e6+10;bool vis[maxn];
    int ans1,T,n,mu[maxn],tot,pri[maxn],phi[maxn],sum[maxn];
    tr1::unordered_map<int,long long>w1;
    tr1::unordered_map<int,int>w;
    long long ans2,sum1[maxn];
    void prepare()
    {
        mu[1]=1,phi[1]=1;
        for(rg int i=2;i<=4e6;i++)
        {
            if(!vis[i])pri[++tot]=i,mu[i]=-1,phi[i]=i-1;
            for(rg int j=1;j<=tot&&pri[j]*i<=4e6;j++)
            {
                vis[i*pri[j]]=1;
                if(!(i%pri[j])){phi[i*pri[j]]=phi[i]*pri[j];break;}
                else mu[i*pri[j]]=-mu[i],phi[i*pri[j]]=phi[i]*phi[pri[j]];
            }
        }
        for(rg int i=1;i<=4e6;i++)sum[i]=sum[i-1]+mu[i],sum1[i]=sum1[i-1]+phi[i];
    }
    int solvemu(int n)
    {
        if(n<=4e6)return sum[n];
        if(w[n])return w[n];
        int ans=1;
        for(rg int i=2,j;i<=n;i=j+1)
        {
            j=n/(n/i);
            ans-=(j-i+1)*solvemu(n/i);
        	if(j==n)break;
    	}
        return w[n]=ans;
    }
    long long solvephi(int n)
    {
        if(n<=4e6)return sum1[n];
        if(w1[n])return w1[n];
        long long ans=(1ll+n)*n/2;
        for(rg int i=2,j;i<=n;i=j+1)
        {
            j=n/(n/i);
            ans-=(j-i+1)*solvephi(n/i);
        	if(j==n)break;
        }
        return w1[n]=ans;
    }
    signed main()
    {
        read(T),prepare();
        while(T--)
        {
            read(n);
            printf("%lld %d
    ",solvephi(n),solvemu(n));
        }
    }
    
  • 相关阅读:
    C++11——Lambda表达式
    匿名空间使用
    C++11——可调用对象包装器、绑定器
    winhttp 发送https的get请求
    C++11——基于范围的for循环
    C++11——列表初始化
    C++11——委托构造和继承构造函数
    C++11——using的使用
    使用appnium,Uiautomatorviewer连接手机报错:Unexpected error while obtaining UI hierarchy java.lang.reflect.Invocation【已解决】
    逆向 | IATHook 全屏加速挂
  • 原文地址:https://www.cnblogs.com/lcxer/p/10549066.html
Copyright © 2020-2023  润新知