题意:给你1~n的数字,问你一个集合中的lcm大于m的集合有多少个
思路:这个题挺有意思的,我们直接的可以想到爆枚的话的复杂度有2^40,但是这些数中的lcm的答案缺不会有很多,最多也就是这40个数的lcm,所以不会有很大,那这样的话我们用一个map来记录dp[i]代表当前是有前i个数,对于每i个数的map<i,j>,我们定义lcm为i的有j个,这样我们就可以转移了
代码:
#include <cstdio> #include <map> #include <cstring> using namespace std; typedef long long LL; LL gcd(LL a,LL b){ return b==0?a:gcd(b,a%b); } LL lcm(LL a, LL b){ return a*b/gcd(a,b); } map<LL,LL> dp[45]; map<LL,LL>::iterator it; void init() { dp[1][1]=1; for(int i=2;i<=40;i++){ dp[i]=dp[i-1]; dp[i][i]+=1; for(it=dp[i-1].begin();it!=dp[i-1].end();it++){ LL as=lcm(it->first,i); dp[i][as]+=it->second; } } } int main() { init(); int T,t; scanf("%d",&T); int cas=1; while(T--){ int n;LL m; scanf("%d%lld",&n,&m); printf("Case #%d: ",cas++); LL ans=0; for(it=dp[n].begin();it!=dp[n].end();it++){ if(it->first>=m)ans+=it->second; } printf("%lld ",ans); } return 0; }