BestCoder Round #84

  1001,预处理出所有2的幂次数,然后从最大的开始找就行。但是最大的位置应当是从i=min(tot,m)开始,因为如果m很大,比tot还大,那么2^m根本没存下来,或者说num[i]是0,结果就会出现整数除以0的错误了(我一开始就是这样的= =);另外如果m很小,如果n同时很大,不能从tot开始找,因为最大的数不是2^tot,必须从2^m开始找。还好当时凭借直觉这么写然后AC了- -,不然又是WA到死。。代码如下:

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <math.h>
 4 #include <vector>
 5 #include <map>
 6 #include <set>
 7 #include <iostream>
 8 #include <string.h>
 9 #include <math.h>
10 using namespace std;
11 typedef long long ll;
12 typedef pair<int,int> pii;
13 
14 int num[100];
15 int tot = 0;
16 
17 int main()
18 {
19     int now = 1;
20     num[0] = 1;
21     while(now<=1e9)
22     {
23         now <<= 1;
24         num[++tot] = now;
25     }
26 
27 
28     int n,m;
29     int T;
30     cin>>T;
31     while(T--)
32     {
33         scanf("%d%d",&n,&m);
34         int sum = 0;
35         for(int i=min(m,tot);i>=0;i--)
36         {
37             if(num[i]>n) continue;
38             int t = n/num[i];
39             sum += t;
40             n -= t*num[i];
41             if(n==0) break;
42         }
43         cout << sum<<endl;
44     }
45 }
View Code

  1002,想说明的一点是,在for的过程中,如果lower_bound找的是a[i],那么意义是,以i这个位置结尾的最长的lis的长度;如果找的是inf,那么意义是,从第一个位置到i这个位置为止,最长出现的lis的长度。这两点要搞清楚。代码如下:

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <math.h>
 4 #include <vector>
 5 #include <map>
 6 #include <set>
 7 #include <iostream>
 8 #include <string.h>
 9 #include <math.h>
10 using namespace std;
11 typedef long long ll;
12 typedef pair<int,int> pii;
13 const int N = 1e5 + 5;
14 const int inf = 0x3f3f3f3f;
15 
16 int dp[N],lis[N];
17 int a[N];
18 int ans[N];
19 
20 int main()
21 {
22     int T;cin>>T;
23     while(T--)
24     {
25         int n;
26         scanf("%d",&n);
27         for(int i=0;i<n;i++) scanf("%d",a+i);
28         fill(dp,dp+n,inf);
29         memset(lis,0,sizeof(lis));
30         for(int i=0;i<n;i++)
31         {
32             *lower_bound(dp,dp+n,a[i]) = a[i];
33             lis[i] = lower_bound(dp,dp+i+n,a[i]) - dp + 1;
34         }
35 
36         /*for(int i=0;i<n;i++)
37         {
38             printf("%d !!
",lis[i]);
39         }*/
40 
41         memset(ans,0,sizeof(ans));
42         ans[0] = 1;
43         /*for(int i=1;i<n;i++)
44         {
45             if(lis[i] > lis[i-1])
46             {
47                 ans[i] = ans[i-1] + 1;
48             }
49             else if(lis[i] == lis[i-1])
50             {
51                 ans[i] = 1;
52             }
53         }*/
54         for(int i=0;i<n;i++)
55         {
56             printf("%d%c",lis[i],i==n-1?'
':' ');
57         }
58     }
59 }
View Code

  1004,一开始的思路是找不大于d的质数,并且他俩的乘积小于n,,WA到死。后来看了题解才懂应该找的是小于等于d的最小质因数的质数的个数。原因是我的方法没有考虑到d本身不是质数的情况,例如35,找到5就应该停止了,因为再找7的话,35=5*7,7*7=49,这样35就不是最小的因子了。代码如下:

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <math.h>
 4 #include <vector>
 5 #include <map>
 6 #include <set>
 7 #include <iostream>
 8 #include <string.h>
 9 #include <math.h>
10 using namespace std;
11 typedef long long ll;
12 typedef pair<int,int> pii;
13 const int N = 400000 + 5;
14 const int inf = 0x3f3f3f3f;
15 
16 int prime[N];
17 bool isprime[N];
18 int tot = 0;
19 
20 // 找x的最小质因数
21 int mp(int x)
22 {
23     for(int i=1;i<=tot;i++)
24     {
25         int p = prime[i];
26         if(x % p == 0) return p;
27     }
28     return x;
29 }
30 
31 int main()
32 {
33     //prime[0] = 2;
34     memset(isprime,true,sizeof(isprime));
35     for(int i=2;i<N;i++)
36     {
37         if(isprime[i])
38         {
39             prime[++tot] = i;
40             for(int j=2*i;j<N;j+=i)
41             {
42                 isprime[j] = false;
43             }
44         }
45     }
46     // N的范围只要在sqrt(1e9)以内即可
47     
48 
49     int T;cin>>T;
50     while(T--)
51     {
52         int n,x;
53         scanf("%d%d",&n,&x);
54         int sum=0;
55         
56         // 如果直接再加上一个条件,要找的质数还要小于等于x的最小质因数的话,会超时
57         // 因为如果x是质数,mp(x)和for一直找到不大于x的质数,复杂度都是线性的,
58         // 而下面的for复杂度是开了根号的
59         // 而如果x是质数的话,其实只要二分查找不大于x的质数个数有多少个即可,复杂度只有log程度
60         //int t = mp(x);
61         int i;
62         // 如果x不是一个质数,那么,找x的最小的质因数
63         for(i=1;i<=tot && 1LL*prime[i] * prime[i]<= 1LL*x && 1LL*prime[i]*x<(ll)n;i++)
64         {
65             int p = prime[i];
66             sum ++;
67             if(x % p == 0) break;
68         }
69         // 下面的二分是针对x本身也是一个质数的情况
70         if(1LL*prime[i] * prime[i] > 1LL*x)
71         {
72             int l = 1, r = tot;
73             while(l <= r)
74             {
75                 int mid = l + r >> 1;
76                 int p = prime[mid];
77                 if(1LL*p * x >= 1LL*n || p>x)
78                 {
79                     r = mid - 1;
80                 }
81                 else
82                 {
83                     sum = mid;
84                     l = mid + 1;
85                 }
86             }
87         }
88         printf("%d
",sum);
89     }
90 }
View Code
原文地址:https://www.cnblogs.com/zzyDS/p/5700115.html