zoukankan      html  css  js  c++  java
  • 1101 Quick Sort (25分)

    开始觉得是个什么两次遍历法,后来发现是RMQ问题,可以选择线段树,树状数组,ST表三种
    再看数据范围:(N <= 10^5)
    线段树/树状数组:(O(nlogn))
    ST表:(O(n))

    #include<iostream>
    #include<cmath>
    #include<vector>
    #include<algorithm>
    
    using namespace std;
    
    const int N = 100010;
    
    int a[N];
    int maxv[N][20], minv[N][20];
    int n;
    vector<int> res;
    
    void init(){
        int k = log(n) / log(2);
        
        for(int i = 1; i <= n; i ++) maxv[i][0] = a[i];
        for(int i = 1; i <= n; i ++) minv[i][0] = a[i];
        
        for(int j = 1; j <= k; j ++)
            for(int i = 1; i + (1 << j) - 1 <= n; i ++){
                maxv[i][j] = max(maxv[i][j - 1], maxv[i + (1 << j - 1)][j - 1]);
                minv[i][j] = min(minv[i][j - 1], minv[i + (1 << j - 1)][j - 1]);
            }
    }
    
    int query_max(int l, int r){
        if(r < l) return -1;
        int k = log(r - l + 1) / log(2);
        return max(maxv[l][k], maxv[r - (1 << k) + 1][k]);
    }
    
    int query_min(int l, int r){
        if(r < l) return 0x3f3f3f3f;
        int k = log(r - l + 1) / log(2);
        return min(minv[l][k], minv[r - (1 << k) + 1][k]);
    }
    
    int main(){
        cin >> n;
        
        for(int i = 1; i <= n; i ++) cin >> a[i];
        
        init();
        
        for(int i = 1; i <= n; i ++){
            int l = query_max(1, i - 1), r = query_min(i + 1, n);
            // cout << l << ' ' << r << endl;
            if(l < a[i] && r > a[i]) res.push_back(a[i]);
        }
        
        sort(res.begin(), res.end());
        
        cout << res.size() << endl;
        
        if(res.size()){
            cout << res[0];
            for(int i = 1; i < res.size(); i ++) cout << ' ' << res[i]; 
        }else puts("");
        
        return 0;
    }
    

    两次遍历法:(O(n))

    #include<iostream>
    #include<vector>
    #include<algorithm>
    
    using namespace std;
    
    const int N = 100010;
    
    int minv[N], maxv[N];
    int n;
    int a[N];
    vector<int> res;
    
    int main(){
        cin >> n;
        
        for(int i = 1; i <= n; i ++) cin >> a[i];
        
        maxv[1] = -1;
        minv[n] = 0x3f3f3f3f;
        for(int i = 2; i <= n; i ++) maxv[i] = max(maxv[i - 1], a[i - 1]);
        for(int i = n - 1; i >= 1; i --) minv[i] = min(minv[i + 1], a[i + 1]);
        
        for(int i = 1; i <= n; i ++)
            if(maxv[i] < a[i] && minv[i] > a[i]) res.push_back(a[i]);
            
        sort(res.begin(), res.end());
        
        cout << res.size() << endl;
        
        if(res.size()){
            cout << res[0];
            for(int i = 1; i < res.size(); i ++) cout << ' ' << res[i];
        }else puts("");
        
        return 0;
    }
    
  • 相关阅读:
    DHCP配置实例
    upupw phpmyadmin写shell
    网络配置课学期总结
    c#写一个网站后台扫描器
    移位运算符
    JavaScript 事件
    JS自动爆炸案例
    生成树协议
    暴力操作节点
    为博客园添加统计访问量的工具
  • 原文地址:https://www.cnblogs.com/tomori/p/13757362.html
Copyright © 2011-2022 走看看