單調棧 線段樹

2021-09-25 16:19:49 字數 2076 閱讀 4080

sequence

時間限制:c/c++ 3秒,其他語言6秒

空間限制:c/c++ 524288k,其他語言1048576k

64bit io format: %lld

your are given two sequences a1…na_a1…n​ and b1…nb_b1…n​ .you need to answer max⁡1≤l≤r≤n\displaystyle \max_ \) \times sum(b_)\}1≤l≤r≤nmax​ 。

where min(a) means the minimal value of every element of sequence a, sum(a) means the sum of every element of sequence a .

the first line contains an integer n .

the second line contains n integers meaning a1…na_a1…n​ .

the third line contains n integers meaning b1…nb_b1…n​ .

an integer meaning the answer.
示例1

複製

3

1 -1 1

1 2 3

複製

//!!!線段樹4倍空間

long long sum[3000006],mx[4*3000006],mn[4*3000006],mx,mn,ans=-1e18;

void up(int o,int l,int r)

int mid= (l+r)/2;

up(o*2,l,mid);

up(o*2+1,mid+1,r);

mx[o]=max(mx[o*2],mx[o*2+1]);

mn[o]=min(mn[o*2],mn[o*2+1]);

//同時建兩顆線段樹

}void que(int o,int l,int r,int ql,int qr)//查詢區域內最值

int mid= (l+r)/2;

if(ql<=mid) que(o*2,l,mid,ql,qr);

if(qr>mid) que(o*2+1,mid+1,r,ql,qr);

}void go()

else

}}int main()

for(int i=1;i<=n;i++)

for(int i=1;i<=n;i++)

if(stk.empty())

else

} //單調棧 l[i] 儲存a[i] 的最左範圍下標 使得在這個範圍內 a[i]為最小值

while(!stk.empty())

//stack無 .clear() 則需要手動清空

for(int i=n;i>=1;i--)

if(stk.empty())

else r[i]=stk.top()-1;

stk.push(i);

} //單調棧 l[i] 儲存a[i] 的最左範圍下標 使得在這個範圍內 a[i]為最小值

up(1,0,n);//建立 字首和 最大最小樹

go();//列舉每個點作為最小值的情況 ,取最大值

printf("%lld\n",ans);

}

NOIP模擬 奇襲 線段樹 單調棧

題意 給定數列,求有多少個區間滿足區間最大 1 區間最小 區間長度 滿足條件為 m ax 1 m in r 1 l ma x mi n r lmax 1 min r 1 l max min r l max 1 min r 1 l ma x mi n r lma x mi n l rmax min l...

最大數(線段樹 單調棧)

寫線段樹的話太裸了,但是題意非常難搞,認真讀題 其中t是最近一次查詢操作的答案 如果還未執行過查詢操作,則t 0 並將所得結果對乙個固定的常數d取模,將所得答案插入到數列的末尾。重新賦值 從題解上看到一種單調棧的寫法覺得非常巧妙 利用了題目的特性 每次都是在最後詢問,用單調棧維護,開兩個棧乙個儲存下...

BZOJ3956 Count(單調棧 線段樹)

傳送門 感覺這道題蘊含了一些十分巧妙的性質。可以發現好點對實際上很少,最多不超過2n個。當乙個點作為點對中的較小點的時候,最多只能和它左邊第乙個大於等於它的點以及它右邊第乙個大於等於它的點配對。維護乙個單調遞減的棧就可以求出所有的好點對。還可以發現對於一段詢問的區間,找出區間中最大的點的位置,那麼區...