最近做了好多CF的题的说,很多cf的题都很有启发性觉得很有必要总结一下,再加上上次写题解因为太简单被老师骂了,所以这次决定总结一下,也发表一下停课一星期的感想= =

Codeforces 261E Maxim and Calculator

描述:有两个变量a和b,初始值为1和0,每次有两种操作,一个是a=a*b,另一个是b++,求有多少个l<a<r能在p步内达到(p<=100,r<1e9)

首先观察到p最大为100,也就是说最大质因数小于p,打表可得一共大概只有300万个数

考虑dp,设dp[i][j]为当b最多为i时最多须多少次才能a=a*b操作达到j状态,可得f[i][j]=min(f[i-1][j],f[i-1][j/i]+1)

时间复杂度O(np)可以解决这个问题

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 #define maxn 3000001
 7 #define maxq 101
 8 int f[maxn],p[300],id[maxn],n,r,le,num;
 9 bool b[maxn];
10 int dfs(int x,int y) {
11     id[++n]=y;
12     for (int i=x;i<=num;i++) {
13         if (y*1ll*p[i]>r) break;
14         dfs(i,y*p[i]);
15     }
16     return 0;
17 }
18 int main(){
19     int le,k;
20 //    freopen("1.in","r",stdin);
21 //    freopen("1.out","w",stdout);
22     scanf("%d%d%d",&le,&r,&k);
23     for (int i=2;i<=k;i++) {
24         if (!b[i]) p[++num]=i;
25         for (int j=1;j<=num&&i*p[j]<=k;j++) {
26             b[i*p[j]]=1;
27             if (!(i%p[j])) break;
28         }
29     }
30     dfs(1,1);
31     f[1]=0;
32     for (int i=2;i<=n;i++) f[i]=300;
33     sort(id+1,id+1+n);
34     for (int i=1;i<=k;i++) {
35         int t=1;
36         for (int j=1;j<=n;j++) {
37             while (t<=n&&id[t]!=id[j]*i) ++t;
38             if (t>n) break;
39             f[t]=min(f[t],f[j]+1);
40             if ((!b[t])&&(i+f[t]<=k)) b[t]=1;    
41         }
42     }
43     int ans=0;
44     for (int i=1;i<=n;i++){
45         if (b[i]&&id[i]>=le) ++ans;
46     }
47     printf("%d\n",ans);
48     return 0;
49 }
View Code

相关文章: