牛客 Fake Maxpooling
阿新 • • 發佈:2020-07-15
題目連結: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 4View Code#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 2021 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 }
給一份 會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