• 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();
    }
  • 相关阅读:
    ExternalInterface.addCallback()方法,as2 和 as3的区别
    关于table的display问题
    关于table的display问题
    js表单验证是否空值的简单处理办法
    《那些年啊,那些事——一个程序员的奋斗史》——112
    《那些年啊,那些事——一个程序员的奋斗史》——111
    《那些年啊,那些事——一个程序员的奋斗史》——113
    《那些年啊,那些事——一个程序员的奋斗史》——115
    《那些年啊,那些事——一个程序员的奋斗史》——112
    《那些年啊,那些事——一个程序员的奋斗史》——115
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5311402.html
Copyright © 2020-2023  润新知