codeforces1454 F. Array Partition

这周忙死,一直没机会吧补一下题,周二晚上打的div3,过了A~E,F就看了下题目就没时间了,无聊的时候想应该会用到ST表,然后想要维护指针,后来写的时候发现维护不了,然后就歇菜了。。。

F. Array Partition

大佬题解
枚举一个断点,然后二分一个断点。
三个区间分别为 [ 1 , i − 1 ] , [ i , m i d ] , [ m i d + 1 , n ] [1,i-1],[i,mid],[mid+1,n] [1,i1],[i,mid],[mid+1,n]

对于枚举的端点 i i i显然 m a x ( 1 , i − 1 ) max(1,i-1) max(1,i1)以固定,考虑如何确定 m i d mid mid

  • m i n ( i , m i d ) > m a x ( 1 , i − 1 ) min(i,mid)>max(1,i-1) min(i,mid)>max(1,i1) 需要扩大中间的区间使 m i n ( i , m i d ) min(i,mid) min(i,mid)变小
  • m i n ( i , m i d ) < m a x ( 1 , i − 1 ) min(i,mid)<max(1,i-1) min(i,mid)<max(1,i1) 需要缩小中间的区间使 m i n ( i , m i d ) min(i,mid) min(i,mid)变大
  • m i n ( i , m i d ) = m a x ( 1 , i − 1 ) min(i,mid)=max(1,i-1) min(i,mid)=max(1,i1)
    1.若 m i n ( i , m i d ) > m a x ( m i d + 1 , n ) min(i,mid)>max(mid+1,n) min(i,mid)>max(mid+1,n) 需要缩小中间的区间
    2.若 m i n ( i , m i d ) < m a x ( m i d + 1 , n ) min(i,mid)<max(mid+1,n) min(i,mid)<max(mid+1,n) 需要扩大中间的区间
    3.找到答案直接输出
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<random>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int mod=998244353;
const int N=200010;
int n,a[N];
int STmn[N][19],STmx[N][19],lg[N];
void pre()
{
    
    
    lg[1]=0;
    for(int i=2;i<=n;i++) lg[i]=lg[i>>1]+1;
    for(int i=1;i<=n;i++) STmx[i][0]=STmn[i][0]=a[i];
    
    for(int j=1;j<=lg[n];j++)
        for(int i=1;i+(1<<j)-1<=n;i++)
        {
    
    
            STmn[i][j]=min(STmn[i][j-1],STmn[i+(1<<j-1)][j-1]);
            STmx[i][j]=max(STmx[i][j-1],STmx[i+(1<<j-1)][j-1]);
        }
}
int qmin(int l,int r)
{
    
    
    int len=lg[r-l+1];
    return min(STmn[l][len],STmn[r-(1<<len)+1][len]);
}
int qmax(int l,int r)
{
    
    
    int len=lg[r-l+1];
    return max(STmx[l][len],STmx[r-(1<<len)+1][len]);
}
int main()
{
    
    
    //IO;
    int T=1;
    cin>>T;
    while(T--)
    {
    
    
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        pre();
        bool ok=0;
        for(int i=2;i<n;i++)
        {
    
    
            if(ok) break;
            int l=i,r=n-1;
            while(l<=r)
            {
    
    
                int mid=l+r>>1;
                if(qmin(i,mid)>qmax(1,i-1)) l=mid+1;
                else if(qmin(i,mid)<qmax(1,i-1)) r=mid-1;
                else
                {
    
    
                    if(qmin(i,mid)>qmax(mid+1,n)) r=mid-1;
                    else if(qmin(i,mid)<qmax(mid+1,n)) l=mid+1;
                    else
                    {
    
    
                        ok=1;
                        cout<<"YES\n";
                        cout<<i-1<<' '<<mid-i+1<<' '<<n-mid<<'\n';
                        break;
                    }
                }
            }
        }
        if(!ok) cout<<"NO\n";
        
    }
    return 0;
}

奇怪的二分~~不会啊!
要加油哦~

猜你喜欢

转载自blog.csdn.net/Fighting_Peter/article/details/110292905