P5746 [NOI2002] 机器人M号
P5746 [NOI2002] 机器人M号 题解
头图
不会告诉你是因为洛谷提交题解被打回来好几次所以决定在博客上复制粘贴的
虽然...但是还是有一些思考量的...
分析
显然:
当 \(i \neq 1\) 时
-
\(i\) 是 \(j\) 的老师 \(\Leftrightarrow i \mid j\)
-
第 \(i\) 号机器人的独立数为 \(\varphi(i)\)
读题,设两个奇素数 \(x,y\) ,分情况讨论:
-
\(x\) 为政客:则 \(x \times y\) 为军人
-
\(x\) 为军人:则 \(x \times y\) 为政客
所以政客和军人只能由不同的奇素数乘起来得到。
考虑DP。
设 \(f(i,j)\) 为前 \(i\) 个质数中,选奇数 \((j=1)\) 或偶数 \((j=0)\) 个质数的答案,则动态转移方程为
\[f(i,j)=f(i-1,j\operatorname{xor}1) \times \varphi(p_i)+f(i-1,j)
\]
学者的独立数只需快速幂求 \(m\) 的值,再减去政客和军人,再减 \(1\) (不明白减 \(1\) 重新爬回去读题 怒)即可。
Elaina's Code
Elaina's Code
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
#define rd read()
#define Elaina 0
inline int read(){
int x=0,f=1;
char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
return x*f;
}
const int mod=10000;
int n,m,f[N][2];
int qpow(int a,int b){
int ret=1;
for(;b;b>>=1){
if(b&1) ret=ret*a%mod;
a=a*a%mod;
}
return ret;
}
signed main(){
int k=rd;
f[0][0]=1;
int cnt=1;
for(int i=1;i<=k;i++){
int p=rd,e=rd;
(cnt*=qpow(p,e))%=mod;
f[i][1]=(f[i-1][0]*(p==2?0:(p-1))%mod+f[i-1][1])%mod;
f[i][0]=(f[i-1][1]*(p==2?0:(p-1))%mod+f[i-1][0])%mod;
}
f[k][0]--;
printf("%lld\n%lld\n%lld\n",(f[k][0]%mod+mod)%mod,f[k][1],((cnt-f[k][0]-f[k][1]-1)%mod+mod)%mod);
return Elaina;
}
都看到这了,真的不点个赞吗(>ω<*)