码迷,mamicode.com
首页 > 编程语言 > 详细

[TJOI2016&HEOI2016] 排序

时间:2018-10-10 23:56:19      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:lse   col   return   turn   lin   problem   print   char   \n   

[题目链接]

          https://www.lydsy.com/JudgeOnline/problem.php?id=4552

[算法]

         首先 , 二分答案x , 将比x小的数看作1,比x大的数看作0

         然后用线段树检验即可

         时间复杂度 : O(MlogN^2)

[代码]

         

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 10;

int n , m , q;
int a[MAXN],b[MAXN];

struct Que
{
        int op , l , r;
} que[MAXN];
struct Node
{
        int l , r;
        int tag , cnt;
} Tree[MAXN << 2];

template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == -) f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - 0;
    x *= f;
}
inline void update(int index)
{
        Tree[index].cnt = Tree[index << 1].cnt + Tree[index << 1 | 1].cnt;
}
inline void build(int index,int l,int r)
{
        Tree[index].l = l; 
        Tree[index].r = r;
        Tree[index].tag = -1;
        if (l == r)
        {
                Tree[index].cnt = b[l];
                return;
        }
        int mid = (l + r) >> 1;
        build(index << 1,l,mid);
        build(index << 1 | 1,mid + 1,r);
        update(index);
}
inline void pushdown(int index)
{
        int l = Tree[index].l , r = Tree[index].r ,
                mid = (l + r) >> 1;
        if (Tree[index].tag != -1)
        {
                if (Tree[index].tag)
                {
                        Tree[index << 1].cnt = mid - l + 1;
                        Tree[index << 1 | 1].cnt = r - mid;
                        Tree[index << 1].tag = Tree[index << 1 | 1].tag = 1;
                } else
                {
                        Tree[index << 1].cnt = Tree[index << 1 | 1].cnt = 0;
                        Tree[index << 1].tag = Tree[index << 1 | 1].tag = 0;
                }
                Tree[index].tag = -1;
        }
}
inline void modify(int index,int l,int r,int value)
{
        if (l > r) return;
        if (Tree[index].l == l && Tree[index].r == r)
        {
                if (value == 1) Tree[index].cnt = Tree[index].r - Tree[index].l + 1;
                else Tree[index].cnt = 0;
                Tree[index].tag = value;
                return;
        }
        pushdown(index);
        int mid = (Tree[index].l + Tree[index].r) >> 1;
        if (mid >= r) modify(index << 1,l,r,value);
        else if (mid + 1 <= l) modify(index << 1 | 1,l,r,value);
        else 
        {
                modify(index << 1,l,mid,value);
                modify(index << 1 | 1,mid + 1,r,value);
        }
        update(index);
}
inline int query(int index,int l,int r)
{
        if (Tree[index].l == l && Tree[index].r == r) return Tree[index].cnt;
        pushdown(index);
        int mid = (Tree[index].l + Tree[index].r) >> 1;
        if (mid >= r) return query(index << 1,l,r);
        else if (mid + 1 <= l) return query(index << 1 | 1,l,r);
        else return query(index << 1,l,mid) + query(index << 1 | 1,mid + 1,r);
}
inline bool check(int x)
{
        for (int i = 1; i <= n; i++) b[i] = (a[i] <= x);
        build(1,1,n);
        for (int i = 1; i <= m; i++)
        {
                if (que[i].op == 0) 
                {
                        int cnt = query(1,que[i].l,que[i].r);
                        modify(1,que[i].l,que[i].l + cnt - 1,1);
                        modify(1,que[i].l + cnt,que[i].r,0);
                } else
                {
                        int cnt = query(1,que[i].l,que[i].r);
                        modify(1,que[i].l,que[i].r - cnt,0);
                        modify(1,que[i].r - cnt + 1,que[i].r,1);
                }
        }        
        return query(1,q,q) == 1;
}

int main()
{
        
        read(n); read(m);
        for (int i = 1; i <= n; i++) read(a[i]);
        for (int i = 1; i <= m; i++)
        {
                read(que[i].op);
                read(que[i].l);
                read(que[i].r);
        }
        read(q);
        int l = 1 , r = n , ans;
        while (l <= r)
        {
                int mid = (l + r) >> 1;
                if (check(mid))
                {
                        ans = mid;
                        r = mid - 1;
                } else l = mid + 1;
        }
        printf("%d\n",ans);
        
        return 0;
    
}

 

[TJOI2016&HEOI2016] 排序

标签:lse   col   return   turn   lin   problem   print   char   \n   

原文地址:https://www.cnblogs.com/evenbao/p/9769525.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!