1. 程式人生 > >BZOJ 1012最大數 [JSOI2008]

BZOJ 1012最大數 [JSOI2008]

嘗試 fine new 結束 onclick class 註意 地方 lan

拿的洛谷的鏈接quq

正解:單調棧+二分查找(or,線段樹?

解題報告:

今天嘗試學習了下單調棧,然後就看到有個博客安利了這個經典例題?於是就去做了,感覺還是幫助了理解趴quqqqqq

但是有個很迷的地方在於,我感覺我理解了這個博客港的單調棧,然後根據這個博客港的做出了這題

這題,首先,一個很顯然的的地方是,我們要維護一個單調遞減的棧

這樣想,如果有一個數,有另一個數比它大還在它右邊,那顯然它的存在是沒有意義的(就像,比你強還比你小的oier,你是註定打不過的)

那如果我們讀入了一個數,它左邊有比它小的數.這些數就都沒有存在的意義了嘛,我們就一一彈掉

你沒有發現!這個的過程!就!很棧嘛!

好滴那按照我目前的理解來說這個就是,單調棧,,,趴?

然後就做完了

唯一要註意的就,詢問的時候我們肯定是根據位置來找的嘛,然後我,很傻不拉幾的,一個個找,,,這就喪失了查找的意義啊!!!喪失了單調的意義啊!!!那那那那我們就沒有充分利用,單調這個東西!

所以我們應該,二分查找

好了結束

(哦對了其實因為單調性我們在彈的時候也可以二分查找,但是不知為何我改進了一下之後WA了,,,然後我又懶得再研究哪兒錯了而且它還不能下數據,,,然後我就懶得再進一步搞了,就這樣趴quqqqqq

那就直接放代碼

技術分享圖片
#include<bits/stdc++.h>
using namespace
std; #define ll long long #define rp(i,x,y) for(register ll i=x;i<=y;++i) #define my(i,x,y) for(register ll i=x;i>=y;--i) ll m,d,top=1,z[200010],wz[200010],t,cnt; inline ll read() { char ch=getchar();ll x=0;bool y=1; while(ch!=- && (ch>9 || ch<0))ch=getchar();
if(ch==-)ch=getchar(),y=0; while(ch>=0 && ch<=9)x=(x<<1)+(x<<3)+(ch^0),ch=getchar(); return y?x:-x; } int main() { m=read();d=read(); rp(i,1,m) { char ch=getchar();while(ch!=Q && ch!=A)ch=getchar(); if(ch==Q){ll l=read();l=cnt-l+1;t=lower_bound(wz+1,wz+top+1,l)-wz;printf("%lld\n",z[t]);t=z[t];} if(ch==A){ll n=read();n=(n+t)%d;while(top>1 && z[top]<n)top--;z[++top]=n;wz[top]=++cnt;} } return 0; }
好滴!完美滴結束!

BZOJ 1012最大數 [JSOI2008]