[数论][欧拉函数]机器人M号

本文介绍了一个关于机器人独立数计算的问题,涉及机器人制造、休息周期、职业分类等概念,并提出了一种利用欧拉函数值进行计算的方法,通过素因子分解来求解政客、军人和学者的独立数之和。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

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

分析

这题扯得有点牵强= =
独立数其实就是欧拉函数值啦
有三个值:
1、奇数个奇素数的积的数的欧拉函数总值[f]
2、偶数个……[g]
3、除此之外的数的欧拉函数总值
然后我们因为知道欧拉函数具有如下性质:
φ(a*b)=φ(a)*φ(b)
φ(p)=p-1 (p为素数)
所以我们发现1、2是可以互相转换的即
f[i]=g[i-1]*(p[i]-1)+f[i-1]
g[i]=f[i-1]*(p[i]-1)+g[i-1]
然后通过很复杂看题解的过程知道3的值就是m-f[k]-g[k]

#include <iostream>
#include <cstdio>
#define rep(i,a,b) for (i=a;i<=b;i++)
const int N=1001;
const int q=10000;
using namespace std;
int k;
struct num {
    int p,c;
}a[N];
int p[N],s[N],m=1;

int Power(int x,int y) {
    int ans=1;
    while (y) {
        if (y&1) ans=ans*x%q;
        x=x*x%q;
        y>>=1;
    }
    return ans;
}

int main() {
    int i;
    scanf("%d",&k);
    rep(i,1,k)
    scanf("%d%d",&a[i].p,&a[i].c);
    p[0]=1;
    if (a[1].p==2) p[1]=1;
    else s[1]=a[i].p-1;
    rep(i,1,k) {
        if (a[i].p==2) continue;
        p[i]=(s[i-1]*(a[i].p-1)%q+p[i-1])%q;
        s[i]=(p[i-1]*(a[i].p-1)%q+s[i-1])%q;
    }
    rep(i,1,k) m=m*Power(a[i].p,a[i].c)%q;
    printf("%d\n%d\n%d",p[k]-1,s[k],((m-s[k]-p[k])%q+q)%q);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值