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 1∼n.
Now he wants to perform two types of operations:
0 l r: Sort a[l..r] in increasing order.
1 l 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,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
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 }