牛客 猜数游戏

版权声明:本文为博主原创文章,欢迎转载。 https://blog.csdn.net/define_danmu_primer/article/details/76162519

###题意:
给定一个只包含Y,N的字符串,第i个位置上为Y代表某个数能被i整除,N代表不能,如果存在满足每个字符上的条件的数,则称这个字符串是合法的。
已知字符串长度求合法的字符串的个数,答案模1e9+7。
###思路:

  1. 如果一个数的质因子超过一个则它位置上的字符是被唯一确定的。

如6

如果2,3为NY,YN,NN,则6上的字符为N
如果2,3位YY,则6上的字符为Y

如12

如果4,3为NY,YN,NN,则6上的字符为N
如果4,3位YY,则6上的字符为Y

所以这样的数可以不用考虑。
2. 在就是只包含一个质因子的数。可以按质因子分类,因为包含不同质因子的数不会互相影响,这样就可以用乘法原理计数,而对于只包含一个质因子的数p(对于2来说,就是2,4,8,16,32,64)在n(即题目中给的字符串长度 )范围内的p的幂次加1即为它的变化的情况数。在把每个质数的贡献乘起来即为所求。
###代码:

#include <bits/stdc++.h>
#define pi acos(-1)
#define pb push_back
#define LL long long
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define local freopen("in.txt","r",stdin)
#define input_fast std::ios::sync_with_stdio(false);std::cin.tie(0)
using namespace std;
const int MOD = 1e9 + 7;
const int INF = 0x7FFFFFFF;
const int MAX = 1000000;
inline void read(int& x){
    int flag = 1; char c; while(((c = getchar()) < '0' || c > '9') && c != '-');
    c == '-' ? (flag = -1, x = 0) : (x = c - '0');
    while((c = getchar()) >= '0' && c <= '9') { x = x * 10 + c - '0'; } x *= flag;
}

bool isprime[1000010];

LL solve(int n){
    LL i, j, tmp, cnt, res = 1;

    for(i = 2; i <= n; ++i){
        if(isprime[i]) continue;
        for(j = i * i; j <= n; j += i)
            isprime[j] = true;
        tmp = i; cnt = 0;
        while(tmp <= n){
            ++cnt;
            tmp *= i;
        }
        res = res * (cnt + 1) % MOD;
    }
    return res;
}
int main(){
    int input; LL ans;

    while(~scanf("%d", &input)){
        memset(isprime, 0, sizeof isprime);
        ans = solve(input);
        printf("%I64d\n", ans);
    }
    return 0;
}

###总结:

  1. 这题也是求1到n的最小公倍数的因子个数
  2. 在n的范围内每个质数的幂次即为1到n的最小公倍数。

猜你喜欢

转载自blog.csdn.net/define_danmu_primer/article/details/76162519