1. 程式人生 > 實用技巧 >牛客 Fake Maxpooling

牛客 Fake Maxpooling

題目連結:https://ac.nowcoder.com/acm/problem/207140

題意:給定n*m的一個矩陣 每個位置上的數為lcm(i,j) 問所有k*k的子矩陣中的最大值的和是多少

思路:暴力求矩陣 時間複雜度 o(n*m*log(n*m)) 如果記憶化的話 可以o (n*m) 但我的做法 空間複雜度上不允許記憶化

求出矩陣後 先每一行 單調佇列 求出長度k 的最大值, 然後每一列 再用一次單調佇列求出 剛剛用行求出的最大值中的 最大值 就可得到結果

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4
#define ull unsigned long long 5 #define pb push_back 6 const int maxn=1e6+10; 7 const int mod=998244353; 8 int a[5005][5005]; 9 int f[5005][5005]; 10 int gcd(int a,int b) 11 { 12 if(b==0) return a; 13 else return gcd(b,a%b); 14 } 15 int lcm(int a,int b) 16 { 17 return a*b/gcd(a,b); 18 } 19 20
21 int main() 22 { 23 ios::sync_with_stdio(false); 24 cin.tie(0); 25 int n,m,k; 26 cin>>n>>m>>k; 27 for(int i=1;i<=n;i++) 28 { 29 for(int j=1;j<=m;j++) 30 { 31 a[i][j]=lcm(i,j); 32 } 33 } 34 for(int i=1;i<=n;i++)
35 { 36 deque<int>q; 37 for(int j=1;j<=m;j++) 38 { 39 while(!q.empty()&&a[i][q.back()]<=a[i][j]) 40 q.pop_back(); 41 if(!q.empty()&&q.front()==(j-k)) 42 q.pop_front(); 43 q.push_back(j); 44 if(j>=k) 45 f[i][j]=a[i][q.front()]; 46 } 47 } 48 for(int i=k;i<=m;i++) 49 { 50 deque<int>q; 51 for(int j=1;j<=n;j++) 52 { 53 while(!q.empty()&&f[q.back()][i]<=f[j][i]) 54 q.pop_back(); 55 if(!q.empty()&&q.front()==(j-k)) 56 q.pop_front(); 57 q.push_back(j); 58 if(j>=k) 59 f[j][i]=f[q.front()][i]; 60 } 61 } 62 ll ans=0; 63 for(int i=k;i<=n;i++) 64 { 65 for(int j=k;j<=m;j++) 66 { 67 ans+=f[i][j]; 68 } 69 } 70 cout<<ans<<'\n'; 71 72 73 74 75 76 77 }
View Code

給一份 會MLE的 記憶化的程式碼

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define ull unsigned long long
 5 #define pb push_back
 6 const int maxn=1e6+10;
 7 const int mod=998244353;
 8 int a[5005][5005];
 9 int f[5005][5005];
10 int dp[5005][5005];
11 int gcd(int a,int b)
12 {
13     if(b==0) return a;
14     if(dp[a][b]) return dp[a][b];
15     return dp[a][b]=gcd(b,a%b);
16 }
17 int lcm(int a,int b)
18 {
19     return a*b/gcd(a,b);
20 }
21 
22 
23 int main()
24 {
25     ios::sync_with_stdio(false);
26     cin.tie(0);
27     int n,m,k;
28     cin>>n>>m>>k;
29     for(int i=1;i<=n;i++)
30     {
31         for(int j=1;j<=m;j++)
32         {
33             a[i][j]=lcm(i,j);
34         }
35     }
36     for(int i=1;i<=n;i++)
37     {
38         deque<int>q;
39         for(int j=1;j<=m;j++)
40         {
41             while(!q.empty()&&a[i][q.back()]<=a[i][j])
42                 q.pop_back();
43             if(!q.empty()&&q.front()==(j-k))
44                 q.pop_front();
45             q.push_back(j);
46             if(j>=k)
47                 f[i][j]=a[i][q.front()];
48         }
49     }
50     for(int i=k;i<=m;i++)
51     {
52         deque<int>q;
53         for(int j=1;j<=n;j++)
54         {
55             while(!q.empty()&&f[q.back()][i]<=f[j][i])
56                 q.pop_back();
57             if(!q.empty()&&q.front()==(j-k))
58                 q.pop_front();
59             q.push_back(j);
60             if(j>=k)
61                 f[j][i]=f[q.front()][i];
62         }
63     }
64     ll ans=0;
65     for(int i=k;i<=n;i++)
66     {
67         for(int j=k;j<=m;j++)
68         {
69             ans+=f[i][j];
70         }
71     }
72     cout<<ans<<'\n';
73 
74 
75 
76 
77 
78 
79 }
View Code

還有一份能過的 篩法求的矩陣的

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define ull unsigned long long
 5 #define pb push_back
 6 const int maxn=1e6+10;
 7 const int mod=998244353;
 8 int a[5005][5005];
 9 int f[5005][5005];
10  
11 int gcd(int a,int b)
12 {
13     if(b==0) return a;
14     else return gcd(b,a%b);
15 }
16 int lcm(int a,int b)
17 {
18     return a*b/gcd(a,b);
19 }
20  
21  
22 int main()
23 {
24     ios::sync_with_stdio(false);
25     cin.tie(0);
26     int n,m,k;
27     cin>>n>>m>>k;
28     for(int i=1;i<=n;i++)
29     {
30         for(int j=1;j<=m;j++)
31         {
32             if(a[i][j])
33                 continue;
34             for(int k=1;k*i<=n&&k*j<=m;k++)
35             {
36                 a[k*i][k*j]=k;
37             }
38         }
39     }
40     for(int i=1;i<=n;i++)
41     {
42         for(int j=1;j<=m;j++)
43         {
44             a[i][j]=i*j/a[i][j];
45         }
46     }
47     for(int i=1;i<=n;i++)
48     {
49         deque<int>q;
50         for(int j=1;j<=m;j++)
51         {
52             while(!q.empty()&&a[i][q.back()]<=a[i][j])
53                 q.pop_back();
54             if(!q.empty()&&q.front()==(j-k))
55                 q.pop_front();
56             q.push_back(j);
57             if(j>=k)
58                 f[i][j]=a[i][q.front()];
59         }
60     }
61     for(int i=k;i<=m;i++)
62     {
63         deque<int>q;
64         for(int j=1;j<=n;j++)
65         {
66             while(!q.empty()&&f[q.back()][i]<=f[j][i])
67                 q.pop_back();
68             if(!q.empty()&&q.front()==(j-k))
69                 q.pop_front();
70             q.push_back(j);
71             if(j>=k)
72                 f[j][i]=f[q.front()][i];
73         }
74     }
75     ll ans=0;
76     for(int i=k;i<=n;i++)
77     {
78         for(int j=k;j<=m;j++)
79         {
80             ans+=f[i][j];
81         }
82     }
83     cout<<ans<<'\n';
84  
85  
86  
87  
88  
89  
90 }
View Code