数据结构(线段树):HDU 5649 DZY Loves Sorting

DZY Loves Sorting

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 294    Accepted Submission(s): 77


Problem Description
  DZY has a sequence a[1..n]. It is a permutation of integers 1n.
  Now he wants to perform two types of operations:
    0 r: Sort a[l..r] in increasing order.
    1 r: 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,mm 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 1n.
  Then m lines follow. In each line there are three integers opt,l,r to indicate an operation.
  Last line contains k.
  (1t50,1n,m100000,1kn,1lrn,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
1 6 2 5 3 4 -> [1 2 5 6] 3 4 -> 1 2 [6 5 4 3] -> 1 [2 5 6] 4 3. At last a[3]=5.
 
  好题,考虑二分的话,维护的只是相对大小,题目就好做了。
 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 const int maxn=100010;
 6 int n,m,k;
 7 int tr[maxn<<2],mark[maxn<<2];
 8 int L[maxn],R[maxn],X[maxn],a[maxn];
 9 
10 void Make_same(int x,int l,int r,int d){
11     tr[x]=(r-l+1)*d;
12     mark[x]=d;
13 }
14 
15 void Push_down(int x,int l,int r){
16     if(mark[x]!=-1){
17         int mid=(l+r)>>1;
18         Make_same(x<<1,l,mid,mark[x]);
19         Make_same(x<<1|1,mid+1,r,mark[x]);
20         mark[x]=-1;
21     }
22 }
23 
24 void Build(int x,int l,int r,int g){
25     mark[x]=-1;
26     if(l==r){
27         tr[x]=a[l]<=g?0:1;
28         return;
29     }
30     int mid=(l+r)>>1;
31     Build(x<<1,l,mid,g);
32     Build(x<<1|1,mid+1,r,g);
33     tr[x]=tr[x<<1]+tr[x<<1|1];
34 }
35 
36 int Query(int x,int l,int r,int a,int b){
37     Push_down(x,l,r);
38     if(l>=a&&r<=b)return tr[x];
39     int mid=(l+r)>>1,ret=0;
40     if(mid>=a)ret=Query(x<<1,l,mid,a,b);
41     if(mid<b)ret+=Query(x<<1|1,mid+1,r,a,b);
42     return ret;
43 }
44 
45 void Mark(int x,int l,int r,int a,int b,int d){
46     if(a>b)return;
47     if(l>=a&&r<=b){
48         Make_same(x,l,r,d);
49         return;
50     }
51     Push_down(x,l,r);
52     int mid=(l+r)>>1;
53     if(mid>=a)Mark(x<<1,l,mid,a,b,d);
54     if(mid<b)Mark(x<<1|1,mid+1,r,a,b,d);
55     tr[x]=tr[x<<1]+tr[x<<1|1];    
56 }
57 
58 bool Check(){
59     for(int i=1;i<=m;i++){
60         int sum=Query(1,1,n,L[i],R[i]);
61         if(X[i]){
62             Mark(1,1,n,L[i],L[i]+sum-1,1);
63             Mark(1,1,n,L[i]+sum,R[i],0);
64         }
65         else{
66             sum=R[i]-L[i]+1-sum;
67             Mark(1,1,n,L[i],L[i]+sum-1,0);
68             Mark(1,1,n,L[i]+sum,R[i],1);
69         }
70     }
71     return Query(1,1,n,k,k);
72 }
73 
74 void Solve(){
75     int lo=1,hi=n;
76     while(lo<=hi){
77         int mid=(lo+hi)>>1;
78         Build(1,1,n,mid);
79         if(Check())lo=mid+1;
80         else hi=mid-1;    
81     }
82     printf("%d\n",lo);
83     return;
84 }
85 int main(){
86     int T;
87     scanf("%d",&T);
88     while(T--){
89         scanf("%d%d",&n,&m);
90         for(int i=1;i<=n;i++)scanf("%d",&a[i]);
91         for(int i=1;i<=m;i++)scanf("%d%d%d",&X[i],&L[i],&R[i]);
92         scanf("%d",&k);
93         Solve();
94     }
95     return 0;
96 }

 

posted @ 2016-04-11 13:14  TenderRun  阅读(249)  评论(0编辑  收藏  举报