zoukankan      html  css  js  c++  java
  • HDU DZY Loves Sorting (二分+线段树)

    题目

    Problem 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

    思路

    题目比较特殊,由于数字是全排列,而且询问只有一次,所以我们选择二分答案,并且把大于等于mid置为1,小于置为0,然后用线段树去进行区间修改,最后询问k点是否为1,进行二分。

    代码实现

    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    #define rep(i,f_start,f_end) for (int i=f_start;i<=f_end;++i)
    #define per(i,n,a) for (int i=n;i>=a;i--)
    #define MT(x,i) memset(x,i,sizeof(x) )
    #define rev(i,start,end) for (int i=start;i<end;i++)
    #define inf 0x3f3f3f3f
    #define mp(x,y) make_pair(x,y)
    #define lowbit(x) (x&-x)
    #define MOD 1000000007
    #define exp 1e-8
    #define N 1000005 
    #define fi first 
    #define se second
    #define pb push_back
    typedef long long ll;
    typedef pair<int ,int> PII;
    typedef pair<int ,PII> PIII;
    ll gcd (ll a,ll b) {return b?gcd (b,a%b):a; }
    
    const int maxn=1e5+7;
    int op[maxn],qr[maxn],ql[maxn],k,a[maxn];
    int n,m;
    struct node {
        int l,r;
        int data,add;
        void update (int val) {
           data= (r-l+1)*val;
           add=val;
        }
    }tree[maxn*4];
    
    inline void buildtree (int k,int l,int r) {
       tree[k].l=l,tree[k].r=r;
       tree[k].data=0;
       tree[k].add=-1;
       if (l==r) return ;
       int mid= (l+r)>>1;
       buildtree (k*2,l,mid);
       buildtree (k*2+1,mid+1,r);
    }
    
    inline void lazydown (int k) {
        if (tree[k].add!=-1) {
            tree[k*2].update (tree[k].add),tree[k*2+1].update (tree[k].add);
            tree[k].add=-1;
        }
    }
    
    inline void update (int k,int l,int r,int val) {
        if (l<=tree[k].l&&r>=tree[k].r) {
            tree[k].update (val);
            return ;
        }
        lazydown (k);
    
        int mid= (tree[k].l+tree[k].r)>>1;
        if (l<=mid) update (k*2,l,r,val);
        if (r>mid) update (k*2+1,l,r,val);
        tree[k].data=tree[k*2+1].data+tree[k*2].data;
         
    }
    
    inline int query (int k,int l,int r) {
        if (l<=tree[k].l&&r>=tree[k].r) return tree[k].data;
        lazydown (k);
    
        int mid= (tree[k].l+tree[k].r)>>1;
        int ans=0;
        if (l<=mid) ans+=query (k*2,l,r);
        if (r>mid) ans+=query (k*2+1,l,r); 
        tree[k].data=tree[k*2].data+tree[k*2+1].data;
        return ans;
    }
    
    bool check (int mid) {
        buildtree (1,1,n);
        rep (i,1,n) {
            if (a[i]>=mid) update (1,i,i,1);
            else update (1,i,i,0);
        }
        rep (i,1,m) {
            int x=query (1,ql[i],qr[i]);
            if (op[i]==0) {
                x=qr[i]-ql[i]+1-x;
                update (1,ql[i],ql[i]+x-1,0);
                update (1,ql[i]+x,qr[i],1);
            }
            else {
                update (1,ql[i],ql[i]+x-1,1);
                update (1,ql[i]+x,qr[i],0);
            }
        }
        if (query (1,k,k)==1) return true;
        return false;
    }
    
    inline void solve () {
        scanf ("%d%d",&n,&m);
        rep (i,1,n) scanf ("%d",&a[i]);
        rep (i,1,m) {
            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)>>1;
           if (check (mid)) l=mid+1,ans=mid;
           else r=mid-1; 
        }
        cout<<ans<<endl;
    }
    
    int  main () {
        // freopen ("data.in","r",stdin);
        int t;
        cin>>t;
        while  (t--) {
            solve ();
        }
        // fclose (stdin);
        return 0;
    }
    
  • 相关阅读:
    redis缓存问题解决方案
    JVM 2-垃圾收集及内存分配策略
    JVM 1-内存管理
    mysql数据库基础
    事务学习
    使用redis分布式锁来解决集群项目的定时任务冲突问题
    Spring AOP学习
    Spring IOC
    java语言基础7--线程相关类
    多重背包的二进制优化——DP
  • 原文地址:https://www.cnblogs.com/hhlya/p/13501947.html
Copyright © 2011-2022 走看看