牛客 Fake Maxpooling ###K ###K //K
题目链接:https://ac.nowcoder.com/acm/problem/207140
题意:给定n*m的一个矩阵 每个位置上的数为lcm(i,j) 问所有k*k的子矩阵中的最大值的和是多少
思路:暴力求矩阵 时间复杂度 o(n*m*log(n*m)) 如果记忆化或者筛法的话 可以o (n*m)
求出矩阵后 先每一行 单调队列 求出长度k 的最大值, 然后每一列 再用一次单调队列求出 刚刚用行求出的最大值中的 最大值 就可得到结果
不能直接 修改a 数组 必须开一个f 数组来记录 不然a数组可能影响到后面的单调队列 数据水了没判出来
没有优化过的版本
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define pb push_back 5 const int maxn =2e5+10; 6 const int mod=998244353; 7 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 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 a[i][j]=lcm(i,j); 33 } 34 } 35 for(int i=1;i<=n;i++) 36 { 37 deque<int>q; 38 for(int j=1;j<=m;j++) 39 { 40 while(!q.empty()&&a[i][q.back()]<=a[i][j]) 41 q.pop_back(); 42 if(!q.empty()&&q.front()==j-k) 43 q.pop_front(); 44 q.push_back(j); 45 if(j>=k) 46 f[i][j]=a[i][q.front()]; 47 } 48 } 49 ll sum=0; 50 for(int j=k;j<=m;j++) 51 { 52 deque<int>q; 53 for(int i=1;i<=n;i++) 54 { 55 while(!q.empty()&&f[q.back()][j]<=f[i][j]) 56 q.pop_back(); 57 if(!q.empty()&&q.front()==i-k) 58 q.pop_front(); 59 q.push_back(i); 60 if(i>=k) 61 sum+=f[q.front()][j]; 62 } 63 } 64 cout<<sum<<'\n'; 65 66 67 68 69 }
能过的记忆化的代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define pb push_back 5 const int maxn =5e3+10; 6 const int mod=1e9+7; 7 int dp[maxn][maxn]; 8 9 int gcd(int a,int b) 10 { 11 if(dp[a][b]) 12 return dp[a][b]; 13 if(b==0) return dp[a][b]=a; 14 else return dp[a][b]=gcd(b,a%b); 15 } 16 int lcm(int a,int b) 17 { 18 return a*b/gcd(a,b); 19 } 20 21 int a[maxn][maxn]; 22 23 24 25 int main() 26 { 27 ios::sync_with_stdio(false); 28 cin.tie(0); 29 int n,m,k; 30 cin>>n>>m>>k; 31 for(int i=1;i<=n;i++) 32 { 33 for(int j=1;j<=m;j++) 34 { 35 a[i][j]=lcm(i,j); 36 } 37 } 38 ll ans=0; 39 for(int i=1;i<=n;i++) 40 { 41 deque<int>q; 42 for(int j=1;j<=m;j++) 43 { 44 while(!q.empty()&&a[i][q.front()]<=a[i][j]) 45 q.pop_front(); 46 if(!q.empty()&&q.back()==j-k) 47 q.pop_back(); 48 q.push_front(j); 49 a[i][j]=a[i][q.back()]; 50 } 51 } 52 /*for(int i=1;i<=n;i++) 53 { 54 for(int j=1;j<=m;j++) 55 { 56 cout<<a[i][j]<<" "; 57 } 58 cout<<'\n'; 59 }*/ 60 for(int i=k;i<=m;i++) 61 { 62 deque<int>q; 63 for(int j=1;j<=n;j++) 64 { 65 while(!q.empty()&&a[q.front()][i]<=a[j][i]) 66 q.pop_front(); 67 if(!q.empty()&&q.back()==j-k) 68 q.pop_back(); 69 q.push_front(j); 70 if(j<k) 71 continue; 72 ans+=a[q.back()][i];; 73 } 74 } 75 cout<<ans<<'\n'; 76 77 78 79 80 81 }
还有一份能过的 筛法求的矩阵的 时间复杂度o(n*m)
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 }

浙公网安备 33010602011771号