日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

牛客多校2 - Fake Maxpooling(线性递推gcd+单调队列)

發布時間:2024/4/11 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 牛客多校2 - Fake Maxpooling(线性递推gcd+单调队列) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:給出一個矩陣 A 的大小,規定其元素 A[ i ][ j ] = lcm( i , j ) ,再給出一個 k ,求所有大小為 k * k 的子矩陣中的最大值之和

題目分析:題目時限給了三秒,可以直接 n * m * logn 去求出矩陣 A ,但題解提供了一種可以線性求解 gcd 的方法,所以可以優化掉一層 log,在求出矩陣 A 后,可以對于每一行,利用單調隊列維護區間最大值,mmax[ i ][ j ] 記錄 A[ i ][ j - k ] : A[ i ][ j ] 的最大值,最后再利用單調隊列,求解一下 mmax[ i - k ][ j ] : mmax[ i ][ j ] 的最大值就是子矩陣 ( i - k , j - k ) ~ ( i , j ) 的最大值了,區間維護最大值的代碼可以參考經典例題:滑動窗口

另外這個題目有點卡內存,如果是 5000 * 5000 的數組的話,最多只能開兩個,所以可以將 A 數組與 mmax 數組進行一個復用

代碼:

#include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=5e3+100;int g[N][N];int mmax[N][N];//mmax[i][j]:max(maze[i][j-k]:maze[i][j])struct Node {int val,id;Node(int val,int id):val(val),id(id){} };int main() { #ifndef ONLINE_JUDGE // freopen("input.txt","r",stdin); // freopen("output.txt","w",stdout); #endif // ios::sync_with_stdio(false);int n,m,k;scanf("%d%d%d",&n,&m,&k);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(!g[i][j])for(int k=1;k*i<=n&&k*j<=m;k++)g[k*i][k*j]=k,mmax[k*i][k*j]=i*j*k;for(int i=1;i<=n;i++){deque<Node>q;for(int j=1;j<=k-1;j++){while(q.size()&&q.back().val<=mmax[i][j])//將比當前值小的數全刪掉(尾部)q.pop_back();q.push_back(Node(mmax[i][j],j));}for(int j=k;j<=m;j++){int left=j-k+1;while(q.size()&&q.back().val<=mmax[i][j])//將比當前值小的數全刪掉(尾部)q.pop_back();q.push_back(Node(mmax[i][j],j));while(q.size()&&q.front().id<left)//將過期的值刪掉(頭部)q.pop_front();mmax[i][j]=q.front().val;}}LL ans=0;for(int j=k;j<=m;j++){deque<Node>q;for(int i=1;i<=k-1;i++){while(q.size()&&q.back().val<=mmax[i][j])//將比當前值小的數全刪掉(尾部)q.pop_back();q.push_back(Node(mmax[i][j],i));}for(int i=k;i<=n;i++){int left=i-k+1;while(q.size()&&q.back().val<=mmax[i][j])//將比當前值小的數全刪掉(尾部)q.pop_back();q.push_back(Node(mmax[i][j],i));while(q.size()&&q.front().id<left)//將過期的值刪掉(頭部)q.pop_front();ans+=q.front().val;}}printf("%lld\n",ans);return 0; }

?

總結

以上是生活随笔為你收集整理的牛客多校2 - Fake Maxpooling(线性递推gcd+单调队列)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。