zoukankan      html  css  js  c++  java
  • UVA

    题目:

    给出k个互不相同的证书组成的序列Ni,判断是否存在4个证书Np、Nq、Nr、Ns(1≤p<q<r<s≤k)使得Nq>Ns>Np>Nr或者Nq<Ns<Np<Nr。

    思路:

    有两种情况<小、最大、最小、大>、<大、最小、最大、小>,枚举第1个和第4个数,用RMQ查询这两个数之间的最大值和最小值,然后根据给出的条件判断一下就可以了。

    看到好多大佬不用RMQ也写出来了,还需要在研究一下。

    代码:

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define MAX 1e3
    #define FRE() freopen("in.txt","r",stdin)
    #define FRO() freopen("out.txt","w",stdout)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> P;
    const int maxn = 100010;
    int pos[maxn],a[maxn];
    int dmin[maxn][20],dmax[maxn][20];
    int mi[maxn],mx[maxn];
    int n;
    
    void InitMinRMQ(){
        mi[0] = -1;
        for(int i=1; i<=n; i++){
            mi[i] = ((i&(i-1))==0) ? mi[i-1]+1:mi[i-1];
            dmin[i][0] = a[i];
        }
        for(int j=1; j<=mi[n]; j++){
            for(int i=1; i+(1<<j)-1<=n; i++){
                dmin[i][j]=min(dmin[i][j-1], dmin[i+(1<<(j-1))][j-1]);
            }
        }
    }
    
    int MinRMQ(int x,int y){
        int k = mi[y-x+1];
        return min(dmin[x][k],dmin[y-(1<<k)+1][k]);
    }
    
    void InitMaxRMQ(){
        mx[0] = -1;
        for(int i=1; i<=n; i++){
            mx[i] = ((i&(i-1))==0) ? mx[i-1]+1:mx[i-1];
            dmax[i][0] = a[i];
        }
        for(int j=1; j<=mx[n]; j++){
            for(int i=1; i+(1<<j)-1<=n; i++){
                dmax[i][j] = max(dmax[i][j-1],dmax[i+(1<<(j-1))][j-1]);
            }
        }
    }
    
    int MaxRMQ(int x,int y){
        int k = mx[y-x+1];
        return max(dmax[x][k], dmax[y-(1<<k)+1][k]);
    }
    
    
    int main(){
        //FRE();
        int kase;
        scanf("%d",&kase);
        while(kase--){
            scanf("%d",&n);
            for(int i=1; i<=n; i++){
                scanf("%d",&a[i]);
                pos[a[i]] = i;
            }
            InitMaxRMQ();
            InitMinRMQ();
            //cout<<MinRMQ(1,n)<<"  "<<MaxRMQ(1,n)<<endl;
            bool ok = false;
            for(int i=1; i<n; i++){
                for(int j=i+1; j<=n; j++){
                    int tmin = MinRMQ(i, j);
                    int tmax = MaxRMQ(i, j);
                    if(a[i]<a[j] && pos[tmax]<pos[tmin]){
                        ok = true;
                    }
                    if(a[i]>a[j] && pos[tmax]>pos[tmin]){
                        ok = true;
                    }
                }
                if(ok)
                    break;
            }
            if(ok)
                printf("YES
    ");
            else
                printf("NO
    ");
        }
        return 0;
    }
  • 相关阅读:
    LeetCode:Remove Nth Node From End of List
    LeetCode:Swap Nodes in Pairs
    LeetCode:Merge Two Sorted Lists
    LeetCode:Maximum Subarray
    LeetCode:Linked List Cycle
    LeetCode:Search Insert Position
    LeetCode:Roman to Integer
    算法程序设计题语言类笔记
    我的小游戏之2048
    LeetCode:Best Time to Buy and Sell Stock II
  • 原文地址:https://www.cnblogs.com/sykline/p/10348784.html
Copyright © 2011-2022 走看看