最近做了好多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 }