题意:要求任意长度的数组,使得其和为x,每个元素gcd=y,求这样数组的数量。
首先,由于每个元素可表示为x[i]*y,所以如果x%y!=0,那么这样的情况是不合法。
所以我们可以将问题转化为求数组元素和为x/y,gcd=1的数组数量。
由插板法可以得到和为x的数字共有2的x-1次方-1个情况。
接着我们可以容斥,减去其含有的每一个因数出现的次数,由于原数的因数的因数还是原数的因数,所以记忆化搜索+递归实现即可。
下附AC代码。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<map> using namespace std; typedef long long ll; const ll mod=1e9+7; map<ll,ll> dp; ll n,m; ll quickpow(ll p,ll k) { ll ans=1; while(k) { if(k&1) { ans=ans*p;ans%=mod; } p=p*p;p%=mod; k>>=1; } return ans; } ll dfs(ll now) { if(now==1) return 1; if(dp[now]!=0) return dp[now]; dp[now]=quickpow(2,now-1)-1; for(ll i=2;i*i<=now;i++) { if(now%i==0) { dp[now]-=dfs(i); if(i*i!=now) dp[now]-=dfs(now/i); dp[now]=(dp[now]%mod+mod)%mod; } } return dp[now]; } int main() { scanf("%I64d%I64d",&m,&n); if(n%m) { printf("0n"); return 0; } ll need=n/m; printf("%I64dn",dfs(need)); }
最后
以上就是可爱纸鹤最近收集整理的关于codeforces 900d Unusual Sequences的全部内容,更多相关codeforces内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复