您的位置:首页 > 其它

bzoj 1408: [Noi2002]Robot(数论+DP)

2018-03-05 13:34 411 查看

传送门

http://www.lydsy.com/JudgeOnline/problem.php?id=1408

题解

独立数就是φ,老师就是约数(不算1)。

题目要求的就是由偶数个不同奇质数的积组成的数的φ之和,由奇数个不同奇质数的积组成的数的φ之和,以及m的所有约数的φ之和与前两个值的差。

设f[i]表示前i个质数取奇数个的答案,g[i]为前i个质数取偶数个的答案,然后由于φ是积性函数,所以每个质数是独立的,计算时直接把答案乘起来,根据乘法分配律,就可以进行转移。

还有要特判质数为2的情况。因为∑d|mφ(m)=m,除去1,第三个答案就是m−f[k]−g[k]−1,其中m可用快速幂直接算出。

代码

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
#define Mod 10000
#define maxn 1010

using namespace std;

int k, m, st;
int p[maxn], e[maxn];
int f[maxn], g[maxn];

int Pow(int x, int y){
int res = 1;
for(; y; x = x * x % Mod, y >>= 1)
if(y & 1)  res = res * x % Mod;
return res;
}

int main(){

scanf("%d", &k);

m = 1;

for(int i = 1; i <= k; i++){
scanf("%d%d", &p[i], &e[i]);
m = (m * Pow(p[i], e[i])) % Mod;
}

if(p[1] == 2)  st = 2;
else  st = 1;

f[st] = p[st] - 1;

for(int i = st+1; i <= k; i++){
f[i] = (((g[i-1] * (p[i] - 1) % Mod + f[i-1]) % Mod + p[i] - 1)) % Mod;
g[i] = (f[i-1] * (p[i] - 1) % Mod + g[i-1]) % Mod;
}

m = (m - 1 - f[k] + Mod) % Mod;
m = (m - g[k] + Mod) % Mod;

printf("%d\n%d\n%d\n", g[k], f[k], m);

return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: