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;
}
原文地址:https://www.cnblogs.com/hhlya/p/13501947.html