• bzoj3629 [JLOI2014]聪明的燕姿——DFS+约数和定理


    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3629

    扫除了一个知识盲点:约数和定理

    约数和定理:

    对于一个大于1正整数n可以分解质因数:n=p1^a1*p2^a2*p3^a3*…*pk^ak,则由约数个数定理可知n的正约数有(a₁+1)(a₂+1)(a₃+1)…(ak+1)个,那么n的(a₁+1)(a₂+1)(a₃+1)…(ak+1)个正约数的和为f(n)=(p1^0+p1^1+p1^2+…p1^a1)(p2^0+p2^1+p2^2+…p2^a2)…(pk^0+pk^1+pk^2+…pk^ak)

    所以就可以搜索了,可是我搜索好蒻啊不会...

    参考这篇博客:https://blog.csdn.net/eolv99/article/details/39644419

    于是写了一下,但感觉还是没有领悟设计 dfs 的方法...

    另外,输出那里注释掉的写法为什么一直WA明明我觉得没什么问题啊...

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int const maxn=1e5;
    int s,pri[maxn+5],ans[maxn+5],cnt,num;
    bool vis[maxn+5];
    void init()
    {
        vis[1]=1;
        for(int i=2;i<=maxn;i++)
        {
            if(!vis[i])pri[++cnt]=i;
            for(int j=1;j<=cnt&&i*pri[j]<=maxn;j++)
            {
                vis[i*pri[j]]=1;
                if(i%pri[j]==0)break;
            }
        }
    }
    bool ispri(int x)
    {
        if(x<=maxn)return !vis[x];
    //    for(int i=2;i*i<=x;i++)
    //        if(x%i==0)return 0;
        for(int i=1;pri[i]*pri[i]<=x;i++)
            if(x%pri[i]==0)return 0;
        return 1;
    }
    void dfs(int last,int nw,int tot)
    {
        if(tot==1){ans[++num]=nw; return;}
        if(tot-1>pri[last]&&ispri(tot-1))//tot-1>pri[last],否则可能之后被枚举到 
        {
            ans[++num]=nw*(tot-1); //此处不return  
        }
        for(int i=last+1;pri[i]*pri[i]<=tot;i++)
            for(int t=pri[i],ts=pri[i]+1;ts<=tot;t*=pri[i],ts+=t)//+1是pri[i]^0 
                if(tot%ts==0)//!
                    dfs(i,nw*t,tot/ts);
    }
    int main()
    {
        init();
        while(~scanf("%d",&s))
        {
            num=0;
            dfs(0,1,s);
            sort(ans+1,ans+num+1);
            printf("%d
    ",num);
    //        for(int i=1;i<num;i++)printf("%d ",ans[i]);
    //        printf("%d
    ",ans[num]);
            for(int i=1;i<=num;i++)
            {
                printf("%d",ans[i]);
                if(i==num)printf("
    "); else printf(" ");
            }
        }
        return 0;
    }
  • 相关阅读:
    局部变量、结构体和main函数
    类、对象和方法
    Archiver 浅析
    NSArry的常见方法
    iOS 键盘隐藏
    //获取拼音首字母
    UI通过UISlider编写游戏第六感
    UI中各种手势的使用点击,捏合,清扫,旋转,平移,边缘移动,长按
    IOS学习笔记 -- Modal和Quartz2D
    多控制器管理练习 -- 私人通讯录
  • 原文地址:https://www.cnblogs.com/Zinn/p/9265221.html
Copyright © 2020-2023  润新知