zoukankan      html  css  js  c++  java
  • [NOI2002] Robot 解题报告(数论+DP)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1408

    Description

    3030年,Macsy正在火星部署一批机器人。 第1秒,他把机器人1号运到了火星,机器人1号可以制造其他的机器人。 第2秒,机器人1号造出了第一个机器人——机器人2号。 第3秒,机器人1号造出了另一个机器人——机器人3号。 之后每一秒,机器人1号都可以造出一个新的机器人。第m秒造出的机器人编号为m。我们可以称它为机器人m号,或者m号机器人。 机器人造出来后,马上开始工作。m号机器人,每m秒会休息一次。比如3号机器人,会在第6,9,12,……秒休息,而其它时间都在工作。 机器人休息时,它的记忆将会被移植到当时出生的机器人的脑中。比如6号机器人出生时,2,3号机器人正在休息,因此,6号机器人会收到第2,3号机器人的记忆副本。我们称第2,3号机器人是6号机器人的老师。 如果两个机器人没有师徒关系,且没有共同的老师,则称这两个机器人的知识是互相独立的。注意:1号机器人与其他所有机器人的知识独立(因为只有1号才会造机器人),它也不是任何机器人的老师。 一个机器人的独立数,是指所有编号比它小且与它知识互相独立的机器人的个数。比如1号机器人的独立数为0,2号机器人的独立数为1(1号机器人与它知识互相独立),6号机器人的独立数为2(1,5号机器人与它知识互相独立,2,3号机器人都是它的老师,而4号机器人与它有共同的老师——2号机器人)。 新造出来的机器人有3种不同的职业。对于编号为m的机器人,如果能把m分解成偶数个不同奇素数的积,则它是政客,例如编号15;否则,如果m本身就是奇素数或者能把m分解成奇数个不同奇素数的积,则它是军人,例如编号 3, 编号165。其它编号的机器人都是学者,例如编号2, 编号6, 编号9。 第m秒诞生的机器人m号,想知道它和它的老师中,所有政客的独立数之和,所有军人的独立数之和,以及所有学者的独立数之和。可机器人m号忙于工作没时间计算,你能够帮助它吗? 为了方便你的计算,Macsy已经帮你做了m的素因子分解。为了输出方便,只要求输出总和除以10000的余数。
     

    Input

    输入文件的第一行是一个正整数k(1<=k<=1000),k是m的不同的素因子个数。 以下k行,每行两个整数,pi, ei,表示m的第i个素因子和它的指数(i = 1, 2, …, k)。p1, p2, …, pk是不同的素数。所有素因子按照从小到大排列,即p1<p2<…<pk。输入文件中,2<=pi<10,000, 1<=ei<=1,000,000。

    Output

    输出文件包括三行。 第一行是机器人m号和它的老师中,所有政客的独立数之和除以10000的余数。 第二行是机器人m号和它的老师中,所有军人的独立数之和除以10000的余数。 第三行是机器人m号和它的老师中,所有学者的独立数之和除以10000的余数。
     

    Sample Input

    3 2 1 3 2 5 1

    Sample Output

    8 6 75

    这么长的题面。。。是在告诉我们OI选手必须学好语文吗?

    其实题目中的机器人n独立数就是phi(n),新定义phi(1)=0。机器人n的老师就是n的约数,与某个数有共同老师说明二者不互质。

    直接在已经质因数分解的数上DP就好

    ans1表示到目前质因子政客的独立数之和(即拥有偶数个质因子的数的欧拉函数之和)

    ans2表示到目前质因子军人的独立数之和(即拥有奇数个质因子的数的欧拉函数之和)

    注意不管是军人还是政客的质因子都是互异的

    于是我们得到下面的状态转移方程:

    int z=ans1;
    ans1=(ans1+ans2*(p-1))%mod;//政客 
    ans2=(ans2+(z+1)*(p-1))%mod;//军人 

    因为欧拉函数是积性函数,所以每多加一个质因子p,独立数之和就会乘上p-1;计算ans2时之所以z要加1是因为新加的一个质因数p单独存在也会对答案做出贡献

    那么学者呢?根据题意,不是军人,不是政客,当然也不是1号机器人的就是学者。于是学者的独立数之和等于数m的各个约数的独立数之和-1(1号机器人不算)-政客的独立数之和-军人的独立数之和

    根据欧拉函数的定理之一,一个正整数的各个约数的欧拉函数值之和等于本身的值

    还需要注意2遇到要跳过

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    const int maxn=1000+15;
    const int mod=10000;
    int k,m,ans1,ans2,p,e;
    inline int read()
    {
        char ch=getchar();
        int s=0,f=1;
        while (!(ch>='0'&&ch<='9')) {if (ch=='-') f=-1;ch=getchar();}
        while (ch>='0'&&ch<='9') {s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
        return s*f;
    }
    int pow(int x,int e)
    {
        int r=1;
        while (e)
        {
            if (e&1) r=r*x%mod;
            x=x*x%mod;e>>=1;
        }
        return r;
    }
    int main()
    {
        k=read();
        m=1;
        for (int i=1;i<=k;i++)
        {    
            p=read();e=read();
            m=m*pow(p,e)%mod;
            if (p==2) continue;
            int z=ans1;
            ans1=(ans1+ans2*(p-1))%mod;//政客 
            ans2=(ans2+(z+1)*(p-1))%mod;//军人 
        } 
        printf("%d
    %d
    %d
    ",ans1,ans2,(m-1-ans1-ans2+3*mod)%mod); 
        return 0;
    }
  • 相关阅读:
    (转载)关于一些对location认识的误区
    Python内置数据结构--列表
    Maven
    Python基础语法
    安装ipython和jupyter
    Python环境安装
    Java多线程
    SpringMVC集成springfox-swagger2自动生成接口文档
    SpringMVC拦截器
    SpringMVC异常处理器
  • 原文地址:https://www.cnblogs.com/xxzh/p/9286293.html
Copyright © 2011-2022 走看看