zoukankan      html  css  js  c++  java
  • 数论杂记——约数个数定理

     

     例题:codeforces 1325E

    1. 题目解释每个数的因数个数不超过7个,说明了每个数最多只有2个质因数,因为如果有3个质因数的话,那么 f(n)=(1+1)^3=8>7不成立了。

    2. 求出的答案要使得乘积为完全平方,因此答案的质因数个数必须为偶数个,即a1、a2……要为偶数。

    3. 答案的质因数个数必须为偶数个,等价于选最少的数,使乘积包含的质因子幂次都为 2。如果一个数本身的质因数个数都为偶数,则直接输出1即可,如果没有这样的数,我们可以考虑尝试把每个数的质因数凑在一起,使得质因数个数都为偶数,这样也可以求出答案,如果连凑都凑不出来,则输出-1.

    4. 考虑尝试把每个数凑起来的方法比较巧妙,我们建立一个无向图,每个点代表了一个质因子,如果某个数有两个独立的质因子,也就是说只有这两个质因数凑不了偶数,那么我们就把这两个数连一条边,说明这两个数的个数都为1(入度为1),这有什么用呢?考虑无向图的性质,如果每个点的入度为 2,所以边对应的数的乘积每个质因子幂次都为 2,这就要让我们找出无向图中所存在的最小环。

    这题数论与图论的结合十分巧妙,所以我们要有充足的前备知识才能做得出这道题目。

    #include <bits/stdc++.h>
    #define mp make_pair
    using namespace std;
    typedef long long ll;
    inline int read(){int s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return s*w;}
    const int maxn = 1000005;
    const int INF = 0x3f3f3f3f;
    int ip[maxn],i,n,p[maxn],cnt,dis[maxn],a[maxn],ans;
    bool vis[maxn];
    vector <int> G[maxn];
    void get_prime()
    {
        memset(vis,0,sizeof(vis));
        vis[1]=1;
        p[1]=1;
        ip[1]=1;
        cnt=1;
        for (int i=2;i<=maxn;i++)
        {
            if(!vis[i]) 
            {
                cnt++;
                p[cnt]=i;
                ip[i]=cnt;
            }
            for (int j=1;j<=cnt && i*p[j]<=maxn;j++)
            {
                vis[i*p[j]]=1;
            }
        }
    }
    void add(int x,int y)
    {
        G[x].push_back(y);//to[point++]=y;
        G[y].push_back(x);//to[point++]=x;
    }
    void DIV(int x)
    {
        int div[5],num=0;
        for (int i=2;i<=cnt && p[i]*p[i]<=x;i++)
        {
            if (x % p[i]==0)
            {
                while (x%(p[i]*p[i])==0) x/=p[i]*p[i];
                if (x%p[i]==0) 
                {
                    num++;
                    div[num]=i;
                    x/=p[i];
                }
            }
        }
        if (x>1) 
        {
            num++;
            div[num]=ip[x];
        }
        if (num==0) puts("1"),exit(0);
        else if(num==1) add(1,div[1]);
        else add(div[1],div[2]);
    }
    int bfs(int x)
    {
        queue<pair<int,int> >q;
        q.push(mp(x,0));
        memset(dis,0,sizeof(dis));
        dis[x]=1;
        while (!q.empty())
        {
            int u=q.front().first;
            for (auto v:G[u])
            {
                if (v==q.front().second) continue;
                if (dis[v]) return dis[u]+dis[v]-1;
                q.push(mp(v,u));
                dis[v]=dis[u]+1;
            }
            q.pop();
        }
        return INF;
    }
    int main()
    {
        get_prime();
        n=read();
    //    for (i=1;i<=100;i++) cout<<p[i]<<endl;
        for (i=1;i<=n;i++)
        {
            a[i]=read();
            DIV(a[i]);
        }
        ans=INF;
        for (i=1;i<=1000;i++) 
        {
            ans=min(ans,bfs(i));
        }
        if (ans==INF) cout<<-1<<endl;
            else cout<<ans<<endl;
        return 0;
    }
    View Code

    7

  • 相关阅读:
    Select查询执行顺序
    javascript异步处理
    ASP.NET MVC WebAPI请求
    函数声明和函数表达式
    var声明的成员变量和函数内声明的变量区别
    网页大小自适应方案
    MVC Html.AntiForgeryToken() 防止CSRF攻击
    Jquery跨域请求
    螺旋模型
    快速原型模型
  • 原文地址:https://www.cnblogs.com/Y-Knightqin/p/12518481.html
Copyright © 2011-2022 走看看