数论合集 I

hdu 4662 MU Puzzle

由题意可以得出将U和I都转化为I的方法,得到公式:s + 6 * k = 2^m 

排除某些情况,s必须为偶数,所以 q = s/2; q + 3*k = 2^n 

因为q % 3 != 0, 所以q = 3*a + b (b == 1 || b== 2)

即 3*c + b = 2^n = 2^(2*x + y)  = 2^y*(1+3)^x = 2^y * (1+3*w)

因为y == 0 || y == 1,所以 b== 1 || b == 2 均有解,故q % 3 != 0 即可满足条件

#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 1000005;
#define ok printf("Yes\n")
#define no printf("No\n")
char s[MAXN];
int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    int t;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%s", s);
        int len = strlen(s), p = 0;
        if (s[0] != 'M' || len == 1)
        {
            no; continue;
        }
        for (int i = 1; i< len; ++i)
        {
            if (s[i] == 'M')
            {
                p = -1;
                break;
            }
            p += s[i]=='I'?1:3;
        }
        if (p == -1 )
        {
            no; continue;
        }
        if ((p & 1) == 0 && p %3 != 0 || p == 1)
            ok;
        else
            no;
    }
    return 0;
}


hdu 4675 GCD of Sequence

dp、逆元:费马小定理或辗转相除

#include<cstdio>
#include<algorithm>
#include<vector>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define ll __int64
const int MAXN = 300005;
const ll mod = 1000000007;
ll cc[MAXN];
ll mpower(ll a, ll b)
{
	ll res = 1, p = a;
	while (b)
	{
		if (b & 1) res = res*p%mod;
		p=p*p%mod;
		b >>= 1;
	}
	return res;
}
ll invsele(ll a)
{
	if (a == 1) return 1;
	return invsele(mod%a)*(mod-mod/a)%mod;
}
int n, m, k;
int da[MAXN], mmp[MAXN];
ll dp[MAXN];
int main()
{
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
#endif
	while (scanf("%d%d%d", &n, &m, &k) != EOF)
	{
		memset(mmp, 0, sizeof mmp);
		for (int i = 0; i< n; ++i)
		{
			scanf("%d", da+i);
		 	++mmp[da[i]];
		}
		cc[n-k] = 1;
		for (int i = n-k+1; i<= n; ++i)
		{
			cc[i] = cc[i-1]*invsele(i-n+k)%mod*i%mod;
		}
		for (int i = m; i>= 1; --i)
		{
			int tn = m/i;
			int cnt = 0;
			for (int j = 1; j*i<= m; ++j)
			{
				cnt += mmp[i*j];
			}
			if (n-cnt > k)
			{
				dp[i] = 0;
				continue;
			}
			dp[i] = cc[cnt]*mpower(tn-1, k-n+cnt)%mod*mpower(tn, n-cnt)%mod;
			for (int j = 2; i*j <= m; ++j)
			{
				dp[i] = (dp[i]+mod-dp[i*j])%mod;
			}
		}
		for (int i = 1; i<= m; ++i)
		{
			if (i != 1) printf(" ");
			printf("%I64d", dp[i]);
		}
		puts("");
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值