数论vs图论

最近Mayuyu遇到个神奇的数论题目,Mayuyu能做出来真的不容易啊,描述如下。

题目:给定一个正整数,满足条件,以为根节点进行扩展,对于每一个节点,它只能到达能整除

它的节点,如果存在节点,使得成立,则必定会经过点,对于每一个节

点,有一个值,这个值等于这个节点的最大深度,最后求输出每个节点的序号乘对应值的和。

分析:对于一个数,它只能到达它的所有因子,所以第一步就是找出的所有因子,然后就是如果两个因子出现一

个能整除另一个的情况,就连一条边。最后就构建了一个图,在这个图中,我们从开始进行深度遍历,纪录

到达点的最大深度值,最后加起来就可以了。这里采用链式前向星处理。

代码:

#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <math.h>

using namespace std;
const int N = 5005;
typedef long long LL;

int ct,cnt;
LL fac[N];
int head[N];

struct Edge
{
    int to;
    int next;
    int w;
};

Edge edge[N*N];

void Init()
{
    cnt = 0;
    memset(edge,0,sizeof(head));
    memset(head,-1,sizeof(head));
}

void add(int u,int v,int w)
{
    edge[cnt].to = v;
    edge[cnt].next = head[u];
    edge[cnt].w = w;
    head[u] = cnt++;
}

void Find(LL n)
{
    ct = 0;
    LL t = (LL)sqrt(1.0*n);
    for(int i=1; i<=t; i++)
    {
        if(n % i == 0)
        {
            if(i * i == n) fac[ct++] = i;
            else
            {
                fac[ct++] = i;
                fac[ct++] = n / i;
            }
        }
    }
}

void dfs(int u,int dept)
{
    for(int i=head[u]; ~i; i=edge[i].next)
    {
        int t = edge[i].to;
        edge[t].w = max(edge[t].w, dept + 1);
        dfs(t,dept+1);
    }
}

int main()
{
    LL n;
    while(cin>>n)
    {
        Find(n);
        Init();
        sort(fac,fac+ct);
        for(int i=0; i<ct; i++)
        {
            for(int j=i+1; j<ct; j++)
                if(fac[j] % fac[i] == 0)
                    add(j,i,0);
        }
        dfs(ct-1,1);
        LL ans = 0;
        for(int i=0; i<ct; i++)
            ans += edge[i].w * fac[i];
        cout<<ans + n<<endl;
    }
    return 0;
}

数论vs图论

时间: 2024-10-13 22:42:15

数论vs图论的相关文章

(转) 地区赛获胜策略,赛前默念!

 1. 比赛中评测会有些慢,偶尔还会碰到隔10分钟以上才返回结果的情况,这段时间不能等结果,必须开工其他题,如果WA,两道题同时做.交完每道题都要先打印.2. 比赛时发的饭不是让你当时就吃的,那是给你赛后吃的.基本上比赛中前几名的队都没人吃,除非领先很多.3. 很多选手,尤其是第一次参加比赛的,到一个新环境,全当旅游了,参观的参观,找同学的找同学,玩玩乐乐就把正事抛到脑后了,结果比赛自然没什么好成绩,这样的例子太多了.所以到参赛地后要时刻不忘自己是来比赛的,好好休息.备战.4. 参赛前一天要睡1

转发:dd大牛的《背包九讲》

P01: 01背包问题 题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本思路 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放. 用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值.则其状态转移方程便是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}. 这个方程非常重要,基本上所有跟背包相

背包讲解(剪辑)

第一讲 01背包问题这是最基本的背包问题,每个物品最多只能放一次. 第二讲完全背包问题第二个基本的背包问题模型,每种物品可以放无限多次. 第三讲多重背包问题每种物品有一个固定的次数上限. 第四讲混合三种背包问题将前面三种简单的问题叠加成较复杂的问题. 第五讲二维费用的背包问题一个简单的常见扩展. 第六讲分组的背包问题一种题目类型,也是一个有用的模型.后两节的基础. 第七讲有依赖的背包问题另一种给物品的选取加上限制的方法. 第八讲泛化物品我自己关于背包问题的思考成果,有一点抽象. 第九讲背包问题问

背包九讲

P01: 01背包问题 题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本思路 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放. 用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值.则其状态转移方程便是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}. 这个方程非常重要,基本上所有跟背包相

转载:《背包九讲》

<背包九讲> P01: 01背包问题 题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本思路 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放. 用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值.则其状态转移方程便是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}. 这个方程非常重要,基

矩阵快速幂专题(一)

最近闲来无事,准备集中精力刷一波数论与图论.矩阵快速幂是数论里面的重要组成部分,值得我好好学习一下.因为题目比较多,分析也比较多,所以将此专题分成几个部分.做完这一专题,可能会暂时转向图论部分,然后等我组合数学学得差不多了,再回过头来继续做数论题. 矩阵快速幂算法的核心思想是将问题建模转化为数学模型(有一些简单题目是裸的矩阵模型,但是大部分难题就是难在要构造矩阵,用矩阵方法解决问题),推倒递推式,构造计算矩阵,用快速幂的思想求解矩阵A的n次方取mod,从而得到矩阵里面你需要的数据. 矩阵快速幂问

转载DD大神背包九讲

dd大牛的<背包九讲> P01: 01背包问题 题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本思路 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放. 用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值.则其状态转移方程便是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}. 这个方程非

假期计划

现在假期已经过去一半了,再谈计划已经晚了,但如果不谈就没机会了. 院长让看完刘汝佳,而现在距开学还有大概25天,而现在高效算法,动态规划,数论,图论和高级专题还没看,算起来按照原来的速度肯定是看不完了,不过转念一想每一章都有简单的,肯定很好看,难得大不了一天一个知识点. 做题先以书上的为主,每一章练5道题往上. 激情的假期就要开始了,激情岁月总是让人向往,虽千万人吾往矣.

01背包//简直要被这道题玩死(掀桌)

先上链接: 表格什么的最清楚了:http://blog.csdn.net/mu399/article/details/7722810 dd大大的背包九讲: —————————————————— 01背包的状态转换方程 f[i,j] = Max{ f[i-1,j-Wi]+Pi( j >= Wi ),  f[i-1,j] } f[i,j]表示在前i件物品中选择若干件放在承重为 j 的背包中,可以取得的最大价值. Pi表示第i件物品的价值. 决策:为了背包中物品总价值最大化,第 i件物品应该放入背包中