• bzoj2190: [SDOI2008]仪仗队


    复习一波反演。

    非常粗暴的就是F(1)+2。

    注意范围应该是n-1,因为在坐标系上,只有在原点看,点(1,2)才会挡住(2,4),最后加2就是上面和右边的两个点。

    然而今天在caioj闲逛的时候发现了另外一种做法,就是用phi,抽象一下,设当前点为(x,y)那么应该xy互质才可以看到

    (代码写得很丑,思路不是很清晰)

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int pr,prime[41000],u[41000];
    bool v[41000];
    void mobius_inversion()
    {
        pr=0;u[1]=1;
        memset(v,true,sizeof(v));
        for(int i=2;i<=40000;i++)
        {
            if(v[i]==true)
            {
                prime[++pr]=i;
                u[i]=-1;
            }
            for(int j=1;j<=pr&&i*prime[j]<=40000;j++)
            {
                v[i*prime[j]]=false;
                if(i%prime[j]==0){u[i*prime[j]]=0;break;}
                u[i*prime[j]]=-u[i];
            }
            u[i]+=u[i-1];
        }
    }
    int getF(int n)
    {
        int F=0,last;
        for(int d=1;d<=n;d=last+1)
        {
            last=n/(n/d);
            int G=(n/d)*(n/d);
            F+=(u[last]-u[d-1])*G;
        }
        return F;
    }
    int main()
    {
        mobius_inversion();
        
        int n;
        scanf("%d",&n);
        printf("%d
    ",getF(n-1)+2);
        
        return 0;
    }
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int phi[41000],pr,prime[41000];
    bool v[41000];
    void getprime()
    {
        pr=0;phi[1]=1;
        memset(v,false,sizeof(v));
        for(int i=2;i<=40000;i++)
        {
            if(v[i]==false)
            {
                prime[++pr]=i;
                phi[i]=i-1;
            }
            for(int j=1;j<=pr&&i*prime[j]<=40000;j++)
            {
                v[i*prime[j]]=true;
                if(i%prime[j]==0)
                {
                    phi[i*prime[j]]=phi[i]*prime[j];
                    break;
                }
                else phi[i*prime[j]]=phi[i]*(prime[j]-1);
            }
        }
    }
    int main()
    {
        getprime();
        int n;
        scanf("%d",&n);n--;
        int ans=0;
        for(int i=1;i<=n;i++)ans+=phi[i];
        printf("%d
    ",ans*2+1);
        return 0;
    }
  • 相关阅读:
    DELPHI给整个项目加编译开关
    TThread.Queue和TThread.Synchronize的区别
    中文分词 《第七篇》
    搜索结果的处理和显示《第六篇》
    高级搜索 《第五篇》
    索引管理 《第四篇》
    执行搜索 《第三篇》
    构建索引 《第二篇》
    Lucene.net 基本示例 《第一篇》
    通过配置的方式Autofac 《第三篇》
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8027377.html
Copyright © 2020-2023  润新知