• P5746 [NOI2002] 机器人M号


    题目

    P5746 [NOI2002] 机器人M号

    分析

    这道题足以显示我 (dp) 水平真是菜到家了。。才做了不久又不会了。。

    首先题目里面说:

    对于编号为 (m) 的机器人,如果能把 (m) 分解成偶数个不同奇素数的积,则它是政客,例如编号 (15)

    否则,如果 (m) 本身就是奇素数或者能把 (m) 分解成奇数个不同奇素数的积,则它是军人,例如编号 (3),编号 (165)

    其它编号的机器人都是学者,例如编号 (2), 编号 (6), 编号 (9)

    注意到不同奇素数,发现这样的数很少,但是我们还是没办法暴力,不过,因为要求不同,那么每一个数只有 选/不选 两种情况,这让我们想到了什么,(dp)

    于是设状态 (dp[i,0/1]) 表示:前 (i) 个质因子可以构成的所有数当中,选了偶数个数/奇数个数的所有数的独立数之和。

    根据当前这个质数选和不选两种情况,有转移方程:(large dp[i,v]=dp[i-1,v^1] imes varphi{(prime[i])}+dp[i-1,v])

    然后学者的人数就简单运用减法原理一下即可。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    template <typename T>
    inline void read(T &x){
        x=0;char ch=getchar();bool f=false;
        while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
        while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        x=f?-x:x;
        return ;
    }
    template <typename T>
    inline void write(T x){
        if(x<0) putchar('-'),x=-x;
        if(x>9) write(x/10);
        putchar(x%10^48);
        return ;
    }
    const int N=1e6+5,M=1e6+5,MOD=10000;
    #define ll long long
    int n,p,c,dp[N][2];
    inline int QuickPow(int x,int y){
    	int res=1;
    	while(y){
    		if(y&1) res=res*x%MOD;
    		x=x*x%MOD;
    		y>>=1;
    	}
    	return res;
    }
    int main(){
    	read(n);int tmp=1;
    	dp[0][0]=1;
    	for(int i=1;i<=n;i++){
    		read(p),read(c);
    		tmp=tmp*QuickPow(p,c)%MOD;
    		dp[i][0]=(dp[i-1][1]*(p==2?0:p-1)+dp[i-1][0])%MOD;
    		dp[i][1]=(dp[i-1][0]*(p==2?0:p-1)+dp[i-1][1])%MOD;
    	}
    	dp[n][0]=(dp[n][0]-1+MOD)%MOD;
    	write(dp[n][0]),putchar('
    '),write(dp[n][1]),putchar('
    '),write(((tmp-dp[n][0]-dp[n][1]-1)%MOD+MOD)%MOD);
    	return 0;
    }
    
  • 相关阅读:
    Python编程笔记二进制、字符编码、数据类型
    Python之路Python内置函数、zip()、max()、min()
    替换RTXLogo插件说明
    RTX修改标题logo方法
    RTX和谐说明
    RTX数据表分析
    RTX系统整合记录
    HiMall 3接口鉴权参考
    第三方系统接入
    学习记录
  • 原文地址:https://www.cnblogs.com/Akmaey/p/15169748.html
Copyright © 2020-2023  润新知