版权声明:本文为博主原创文章,欢迎转载。 https://blog.csdn.net/define_danmu_primer/article/details/76162519
###题意:
给定一个只包含Y,N的字符串,第i个位置上为Y代表某个数能被i整除,N代表不能,如果存在满足每个字符上的条件的数,则称这个字符串是合法的。
已知字符串长度求合法的字符串的个数,答案模1e9+7。
###思路:
- 如果一个数的质因子超过一个则它位置上的字符是被唯一确定的。
如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到n的最小公倍数的因子个数
- 在n的范围内每个质数的幂次即为1到n的最小公倍数。