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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

POJ2823 Sliding Window【单调队列】【线段树】【ST表】

發布時間:2024/10/8 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ2823 Sliding Window【单调队列】【线段树】【ST表】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Sliding Window

?POJ - 2823?

題意:

給出一個長度為N的序列,通過一個窗口,可以看到序列中連續的K個元素,窗口從最左邊出發,每次移動一個單位,對于每次移動,輸出當前窗口中的最大值和最小值

單調遞減隊列:從隊頭到隊尾單調遞減的隊列

  • 入隊操作,先把隊尾元素中小于X的元素刪去,將X插入隊尾
  • 出隊操作:隊首元素出隊

例如,A={9,8,3,5,10,6,5},構造一個單調遞減隊列

  • 初始隊列為空,直接將9入隊;隊頭《9】隊尾
  • 8小于9,將8入隊;隊頭《9,8】隊尾
  • 3小于8,將3入隊;隊頭《9,8,3】隊尾
  • 5大于3,將3刪去,然后把5入隊;隊頭《9,8,5】隊尾
  • 把隊列中小于10的元素刪去,然后把10入隊;隊頭《10】隊尾
  • 6小于10,將6入隊;隊頭《10,6】隊尾
  • 5小于10,將5入隊;隊頭《10,6,5】隊尾
#include <iostream> #include <cstdio> #include <cstring> #define MAXN 1000010 using namespace std; int a[MAXN],Q[MAXN],n,k; //維護一個單調遞增隊列,從隊頭到隊尾單調遞增 void get_min() {int head,tail,i;head=1;tail=1;for (i=1;i<=n;i++){while ((head<tail)&&(a[i]<a[Q[tail-1]]))//刪除隊尾元素tail--; //插入隊尾元素Q[tail++]=i;while ((head<tail)&&(Q[head]<i-k+1)) //刪除隊首過時元素head++;/*由于每一層循環只添加一個數,因此每次最多刪除一次隊首,故可改成if語句*///Min[i]=a[Q[head]]; //訪問答案if(i>=k)printf("%d%c",a[Q[head]],i==n?'\n':' ');} } //維護一個單調遞減隊列,從隊頭到隊尾單調遞增 void get_max() {int head,tail,i;head=1;tail=1;for (i=1;i<=n;i++){while ((head<tail)&&(a[i]>a[Q[tail-1]]))tail--;Q[tail++]=i;while ((head<tail)&&(Q[head]<i-k+1))head++;if(i>=k)printf("%d%c",a[Q[head]],i==n?'\n':' ');} } int main() {int i;scanf("%d%d",&n,&k);for (i=1;i<=n;i++)scanf("%d",&a[i]);get_min();get_max();return 0; }

超時

#include<stdio.h> #include<iostream> #include<string.h> #include<queue> #include<cstdio> #include<string> #include<math.h> #include<algorithm> #include<map> #include<set> #include<stack> #define mod 998244353 #define INF 0x3f3f3f3f #define eps 1e-5 #define long long LL using namespace std; const int maxn=1e6+10; int a[maxn]; struct Node{int left,right,Min,Max; }tree[maxn<<2]; void pushup(int rt){tree[rt].Max=max(tree[rt<<1].Max,tree[rt<<1|1].Max);tree[rt].Min=min(tree[rt<<1].Min,tree[rt<<1|1].Min); } void build(int rt,int l,int r){tree[rt].left=l;tree[rt].right=r;if(l==r){tree[rt].Max=tree[rt].Min=a[l];return;}int mid=(tree[rt].left+tree[rt].right)>>1;build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);pushup(rt); } int query_max(int rt,int l,int r){if(tree[rt].left==tree[rt].right){return tree[rt].Max;}int mid=(tree[rt].left+tree[rt].right)>>1;if(r<=mid)return query_max(rt<<1,l,r);else if(l>mid)return query_max(rt<<1|1,l,r);elsereturn max(query_max(rt<<1,l,mid),query_max(rt<<1|1,mid+1,r)); } int query_min(int rt,int l,int r){if(tree[rt].left==tree[rt].right)return tree[rt].Min;int mid=(tree[rt].left+tree[rt].right)>>1;if(r<=mid)return query_min(rt<<1,l,r);else if(l>mid)return query_min(rt<<1|1,l,r);elsereturn min(query_min(rt<<1,l,mid),query_min(rt<<1|1,mid+1,r)); } int main() {int n,k;while(scanf("%d%d",&n,&k)!=EOF){for(int i=1;i<=n;i++){scanf("%d",&a[i]);}if(k==1){for(int i=1;i<=n;i++)printf("%d%c",a[i],i==n?'\n':' ');for(int i=1;i<=n;i++)printf("%d%c",a[i],i==n?'\n':' ');continue;}build(1,1,n);for(int i=1;i<=n;i++){int j=i+k-1;if(j>n) break;printf("%d%c",query_min(1,i,j),j==n?'\n':' ');}for(int i=1;i<=n;i++){int j=i+k-1;if(j>n) break;printf("%d%c",query_max(1,i,j),j==n?'\n':' ');}}return 0; }

?

總結

以上是生活随笔為你收集整理的POJ2823 Sliding Window【单调队列】【线段树】【ST表】的全部內容,希望文章能夠幫你解決所遇到的問題。

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