HDU 5649 DZY Loves Sorting 二分+线段树

DZY Loves Sorting

题目连接:

http://acm.hdu.edu.cn/showproblem.php?pid=5649

Description

DZY has a sequence a[1..n]. It is a permutation of integers 1∼n.

Now he wants to perform two types of operations:

0lr: Sort a[l..r] in increasing order.

1lr: Sort a[l..r] in decreasing order.

After doing all the operations, he will tell you a position k, and ask you the value of a[k].

Input

First line contains t, denoting the number of testcases.

t testcases follow. For each testcase:

First line contains n,m. m is the number of operations.

Second line contains n space-separated integers a[1],a[2],⋯,a[n], the initial sequence. We ensure that it is a permutation of 1∼n.

Then m lines follow. In each line there are three integers opt,l,r to indicate an operation.

Last line contains k.

(1≤t≤50,1≤n,m≤100000,1≤k≤n,1≤l≤r≤n,opt∈{0,1}. Sum of n in all testcases does not exceed 150000. Sum of m in all testcases does not exceed 150000)

Output

For each testcase, output one line – the value of a[k] after performing all m operations.

Sample Input

1
6 3
1 6 2 5 3 4
0 1 4
1 3 6
0 2 4
3

Sample Output

5

Hint

题意

给你n个数1~n的排列,然后有两个操作

1.将[l,r]里面的数按照升序排序

2.将[l,r]里面的数按照降序排序

给你一个k

问你a[k]是多少

题解:

二分答案

每次二分之后,将大于等于mid的置为1,小于的置为0

然后现在升序就很简单了,因为只有0和1,那么把0放在这个区间的前面,把1放在后面就好了

降序同理

然后最后看看a[k]是否等于1就好了

这样复杂度就是mlognlogn的。

涨姿势了

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
int op[maxn],ql[maxn],qr[maxn],n,m,k,a[maxn];
typedef int SgTreeDataType;
struct treenode
{
    int L , R  ;
    SgTreeDataType sum , lazy;
    void update(SgTreeDataType v)
    {
        sum = (R-L+1)*v;
        lazy = v;
    }
};

treenode tree[maxn*4];

inline void push_down(int o)
{
    SgTreeDataType lazyval = tree[o].lazy;
    if(lazyval!=-1)
    {
        tree[2*o].update(lazyval) ; tree[2*o+1].update(lazyval);
        tree[o].lazy = -1;
    }
}

inline void push_up(int o)
{
    tree[o].sum = tree[2*o].sum + tree[2*o+1].sum;
}

inline void build_tree(int L , int R , int o)
{
    tree[o].L = L , tree[o].R = R,tree[o].sum = 0;
    tree[o].lazy = -1;
    if (R > L)
    {
        int mid = (L+R) >> 1;
        build_tree(L,mid,o*2);
        build_tree(mid+1,R,o*2+1);
    }
}

inline void update(int QL,int QR,SgTreeDataType v,int o)
{
    int L = tree[o].L , R = tree[o].R;
    if (QL <= L && R <= QR) tree[o].update(v);
    else
    {
        push_down(o);
        int mid = (L+R)>>1;
        if (QL <= mid) update(QL,QR,v,o*2);
        if (QR >  mid) update(QL,QR,v,o*2+1);
        push_up(o);
    }
}

inline SgTreeDataType query(int QL,int QR,int o)
{
    int L = tree[o].L , R = tree[o].R;
    if (QL <= L && R <= QR) return tree[o].sum;
    else
    {
        push_down(o);
        int mid = (L+R)>>1;
        SgTreeDataType res = 0;
        if (QL <= mid) res += query(QL,QR,2*o);
        if (QR > mid) res += query(QL,QR,2*o+1);
        push_up(o);
        return res;
    }
}
bool check(int mid)
{
    build_tree(1,n,1);
    for(int i=1;i<=n;i++)
        if(a[i]>=mid)update(i,i,1,1);
        else update(i,i,0,1);
    for(int i=1;i<=m;i++)
    {
        int x = query(ql[i],qr[i],1);
        if(op[i]==0)
        {
            x=qr[i]-ql[i]+1-x;
            update(ql[i],ql[i]+x-1,0,1);
            update(ql[i]+x,qr[i],1,1);
        }
        else
        {
            update(ql[i],ql[i]+x-1,1,1);
            update(ql[i]+x,qr[i],0,1);
        }
    }
    if(query(k,k,1)==1)return true;
    return false;
}
void solve()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&op[i],&ql[i],&qr[i]);
    scanf("%d",&k);
    int l=1,r=n,ans=0;
    while(l<=r)
    {
        int mid=(l+r)/2;
        if(check(mid))l=mid+1,ans=mid;
        else r=mid-1;
    }
    cout<<ans<<endl;
}
int main()
{
    int t;scanf("%d",&t);
    while(t--)solve();
}
    原文作者:qscqesze
    原文地址: https://www.cnblogs.com/qscqesze/p/5311402.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞