AtCoder Beginner Contest 132 F - Small Products

数 sqrt 缩小范围

整除分块

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cmath>
  4 #include <cstring>
  5 #include <string>
  6 #include <algorithm>
  7 #include <iostream>
  8 using namespace std;
  9 #define ll long long
 10 
 11 const int maxn=1e5+10;
 12 const ll mod=1e9+7;
 13 const double eps=1e-8;
 14 
 15 ll f[110][maxn],add[maxn],cnt[maxn];
 16 
 17 /**
 18 大于sqrt(maxvalue)的x,
 19 肯定是其它数到x,到从x到其它数
 20 
 21 计数 用 整除分块
 22 **/
 23 
 24 int main()
 25 {
 26     ll n,siz,mid,mmid,l,r,i,j,g=0,sum=0;
 27     scanf("%lld%lld",&siz,&n);
 28     mmid=sqrt(siz+eps);
 29     mid=siz/(mmid+1);
 30     g=0;
 31     for (l=1;l<=siz;l=r+1)
 32     {
 33         ///[l,r]
 34         r=siz/(siz/l);
 35 //        printf("%lld %lld %lld\n",l,r,siz/l);
 36         if (siz/l<=mid)
 37             cnt[siz/l]=r-l+1;
 38     }
 39 
 40     for (j=1;j<=mmid;j++)
 41         f[1][j]=1;
 42     for (i=2;i<=n;i++)
 43     {
 44         g=0;
 45         for (j=1;j<=mmid;j++)
 46             (g+=f[i-1][j])%=mod;
 47         for (j=1;j<=mmid;j++)
 48             f[i][j]=g;
 49 
 50         for (l=1;l<=mid;l++)
 51             add[l]=(add[l-1]+f[i-2][l])%mod;
 52 
 53         g=0;
 54         for (l=mid;l>=1;l--)
 55         {
 56             (g+=add[l]*cnt[l])%mod;
 57             (f[i][l]+=g)%=mod;
 58         }
 59     }
 60 
 61 
 62     for (j=1;j<=mmid;j++)
 63         (sum+=f[n][j])%mod;
 64     for (l=1;l<=mid;l++)
 65     {
 66         add[l]=(add[l-1]+f[n-1][l])%mod;
 67         (sum+=add[l]*cnt[l])%=mod;
 68     }
 69 
 70     ///
 71     memset(f,0,sizeof(f));
 72     g=0;
 73     for (l=mid;l>=1;l--)
 74     {
 75         (g+=cnt[l])%mod;
 76         f[1][l]=g;
 77     }
 78     n--;
 79     for (i=2;i<=n;i++)
 80     {
 81         g=0;
 82         for (j=1;j<=mmid;j++)
 83             (g+=f[i-1][j])%=mod;
 84         for (j=1;j<=mmid;j++)
 85             f[i][j]=g;
 86 
 87         for (l=1;l<=mid;l++)
 88             add[l]=(add[l-1]+f[i-2][l])%mod;
 89 
 90         g=0;
 91         for (l=mid;l>=1;l--)
 92         {
 93             (g+=add[l]*cnt[l])%mod;
 94             (f[i][l]+=g)%=mod;
 95         }
 96     }
 97 
 98     for (j=1;j<=mmid;j++)
 99         (sum+=f[n][j])%mod;
100     for (l=1;l<=mid;l++)
101     {
102         add[l]=(add[l-1]+f[n-1][l])%mod;
103         (sum+=add[l]*cnt[l])%=mod;
104     }
105 
106 
107     printf("%lld",sum);
108     return 0;
109 }
110 /*
111 special
112 100=10*10
113 
114 100 3
115 1 1 100
116 2 2 50
117 3 3 33
118 4 4 25
119 5 5 20
120 6 6 16
121 7 7 14
122 8 8 12
123 9 9 11
124 10 10 10
125 ///
126 11 11 9
127 12 12 8
128 13 14 7
129 15 16 6
130 17 20 5
131 21 25 4
132 26 33 3
133 34 50 2
134 51 100 1
135 
136 
137 23 3
138 1 1 23
139 2 2 11
140 3 3 7
141 4 4 5
142 ///
143 5 5 4
144 6 7 3
145 8 11 2
146 12 23 1
147 
148 
149 31622*log(n) *100
150 
151 10 5
152 1 1 10
153 2 2 5
154 3 3 3
155 
156 4 5 2
157 6 10 1
158 
159 */

猜你喜欢

转载自www.cnblogs.com/cmyg/p/11108256.html