codeforce 686div3 F Array Partition單調棧
Array Partition
You are given an array a consisting of n integers.
Let min(l,r) be the minimum value among al,al+1,…,ar and max(l,r) be the maximum value among al,al+1,…,ar.
Your task is to choose three positive (greater than 0) integers x, y and z such that:
x+y+z=n;
max(1,x)=min(x+1,x+y)=max(x+y+1,n).
In other words, you have to split the array a into three consecutive non-empty parts that cover the whole array and the maximum in the first part equals the minimum in the second part and equals the maximum in the third part (or determine it is impossible to find such a partition).
Among all such triples (partitions), you can choose any.
You have to answer t independent test cases.
Input
The first line of the input contains one integer t (1≤t≤2⋅104) — the number of test cases. Then t test cases follow.
The first line of the test case contains one integer n (3≤n≤2⋅105) — the length of a.
The second line of the test case contains n integers a1,a2,…,an (1≤ai≤109), where ai is the i-th element of a.
It is guaranteed that the sum of n does not exceed 2⋅105 (∑n≤2⋅105).
Output
For each test case, print the answer: NO in the only line if there is no such partition of a that satisfies the conditions from the problem statement. Otherwise, print YES in the first line and three integers x, y and z (x+y+z=n) in the second line.
If there are several answers, you can print any.
Example
input
6
11
1 2 3 3 3 4 4 3 4 2 1
8
2 9 1 7 3 9 4 1
9
2 1 4 2 4 3 3 1 2
7
4 2 1 1 4 1 4
5
1 1 1 1 1
7
4 3 4 3 3 3 4
output
YES
6 1 4
NO
YES
2 5 2
YES
4 1 2
YES
1 1 3
YES
2 1 4
後悔沒看這題…我是真的菜,反而去做了前面那道題,後來賽後看著題,第一反應就是單調棧,只需要列舉每個點作為中間部分的最小值的情況,那麼通過單調棧求出這個數做為最小值的最大連續區間的位置(當然要考慮相等的情況,很明顯只要不是這個數的第一個數或者最後一個數我們就能把他從棧裡面拿走,用map標記一下就好了),這樣貪心的選取,再根據左右區間的最值比較就好了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstring>
#include<stack>
#include<map>
using namespace std;
typedef long long ll;
const int N=2e5+10;
int num[N];
int fmmax[N];
int rmax[N];
int l[N];
int r[N];
int book[N];
int state[N];
int main ()
{
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin>>t;
while(t--)
{
map<int,int>mp;
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>num[i];
fmmax[i]=0;
rmax[i]=0;
if(mp[num[i]]==0)
{
book[i]=1;
mp[num[i]]=1;
}
else book[i]=0;
}
map<int,int>mmap;
for(int i=n;i>=1;i--)
{
if(mmap[num[i]]==0)
{
state[i]=1;
mmap[num[i]]=1;
}
else state[i]=0;
}
rmax[n+1]=0;
for(int i=1;i<=n;i++)
{
fmmax[i]=max(num[i],fmmax[i-1]);
}
for(int i=n;i>=1;i--)
{
rmax[i]=max(num[i],rmax[i+1]);
}
stack<pair<int,int> >s;
for(int i=1;i<=n;i++)
{
while(!s.empty()&&(s.top().first>num[i]||(s.top().first==num[i]&&!book[s.top().second])))
{
s.pop();
}
if(!s.empty())l[i]=s.top().second;
else l[i]=0;
s.push(make_pair(num[i],i));
}
while(!s.empty())s.pop();
for(int i=n;i>=1;i--)
{
while(!s.empty()&&(s.top().first>num[i]||(s.top().first==num[i]&&!state[s.top().second])))
{
s.pop();
}
if(!s.empty())r[i]=s.top().second;
else r[i]=n+1;
s.push(make_pair(num[i],i));
}
int ans=0;
for(int i=1;i<=n;i++)
{
if(fmmax[l[i]]==num[i]&&num[i]==rmax[r[i]])
{
ans=1;
cout<<"YES"<<endl;
cout<<l[i]<<' '<<r[i]-l[i]-1<<' '<<n-r[i]+1<<endl;
break;
}
}
if(!ans)cout<<"NO"<<endl;
}
return 0;
}
相關文章
- 單調棧/單調佇列佇列
- 單調棧 和 單調佇列佇列
- 單調棧和單調佇列佇列
- 單調棧模板
- 淺談單調棧
- ABC372D ABC379F 題解 單調棧二分
- 演算法之單調棧演算法
- 單調棧學習小思考
- 特殊資料結構:單調棧資料結構
- [JSOI2008] 最大數 (單調棧)JS
- HISTOGRA - 最大矩形面積(單調棧)
- 【筆記】線段維護單調棧筆記
- LeetCode Monotone Stack Summary 單調棧小結LeetCodeMono
- 單調棧進階-接雨水-最大矩形
- Leetcode:單調棧_可見山峰問題LeetCode
- codeforce959
- I - Max answer 計蒜客 - 38228 單調棧
- Largest Submatrix of All 1’s(思維+單調棧)
- 【簡單菊花圖】Codeforce 1583Problem - B.md
- codeforce 1700-1900
- Codeforces #123D: 字尾陣列+單調棧3D陣列
- 第十章 單調棧 Part2
- bzoj3190: [JLOI2013]賽車(單調棧)
- Leetcode321. 拼接最大數——單調棧的使用LeetCode
- bzoj1113: [Poi2008]海報PLA(單調棧)
- bzoj1345: [Baltic2007]序列問題Sequence(單調棧)
- 9.6-小訓練 三分小板子+單調棧
- Partition Pruning和Partition-Wise Joins
- HNOI2016序列+資料加強版(字首和+單調棧)
- bzoj1007: [HNOI2008]水平可見直線(單調棧)
- Clique Partition
- 「面向 offer 學演算法」筆面試大殺器 -- 單調棧演算法面試
- 數字右邊第一個大於它的數(單調棧)
- LeetCode C++ 1464. Maximum Product of Two Elements in an Array【Array/Sort】簡單LeetCodeC++
- oracle partition by group by,詳解partition by和group by對比Oracle
- 從簡單的快速排序說起-Partition-ThreePartition-TopK排序TopK
- 分割槽Partition
- 聯賽模擬測試18 A. 施工 單調佇列(棧)優化DP佇列優化