划分树

参考资料:百度百科

 1 #include <iostream> 
 2 #include <cstdio> 
 3 #include <algorithm> 
 4 using namespace std; 
 5    
 6 #define N 100500 
 7    
 8 #define MID ((l+r)>>1) 
 9 int a[N],s[N],t[20][N],num[20][N],n,m; 
10    
11 void Build(int c,int l,int r) 
12 { 
13     int lm=MID-l+1,lp=l,rp=MID+1; 
14     for(int i=l;i<=MID;i++) 
15         lm-=s[i]<s[MID]; 
16     for(int i=l;i<=r;i++) 
17     { 
18         if( i==l ) 
19             num[c][i]=0; 
20         else
21             num[c][i]=num[c][i-1]; 
22         if( t[c][i]==s[MID] ) 
23         { 
24             if( lm ) 
25             { 
26                 lm--; 
27                 num[c][i]++; 
28                 t[c+1][lp++]=t[c][i]; 
29             } 
30             else
31                 t[c+1][rp++]=t[c][i]; 
32         } 
33         else if( t[c][i]<s[MID] ) 
34         { 
35             num[c][i]++; 
36             t[c+1][lp++]=t[c][i]; 
37         } 
38         else
39             t[c+1][rp++]=t[c][i]; 
40     } 
41     if( l<r ) 
42         Build(c+1,l,MID),Build(c+1,MID+1,r); 
43 } 
44    
45 int Query(int c,int l,int r,int ql,int qr,int k) 
46 { 
47     if( l==r ) 
48         return t[c][l]; 
49     int s,ss; 
50     if( l==ql ) 
51         s=0,ss=num[c][qr]; 
52     else
53         s=num[c][ql-1],ss=num[c][qr]-num[c][ql-1]; 
54     if( k<=ss ) 
55         return Query(c+1,l,MID,l+s,l+s+ss-1,k); 
56     else
57         return Query(c+1,MID+1,r,MID+1+ql-l-s,MID+1+qr-l-s-ss,k-ss); 
58 } 
59    
60 int main() 
61 { 
62     scanf("%d%d",&n,&m); 
63     for(int i=1;i<=n;i++) 
64     { 
65         scanf("%d",&a[i]); 
66         s[i]=t[0][i]=a[i]; 
67     } 
68     sort(s+1,s+1+n); 
69     Build(0,1,n); 
70     while( m-- ) 
71     { 
72         int l,r,k; 
73         scanf("%d%d%d",&l,&r,&k); 
74         printf("%d\n",Query(0,1,n,l,r,k)); 
75     } 
76     return 0; 
77 }
View Code

 

posted @ 2014-09-16 16:18  Mr.Youyu  阅读(131)  评论(0)    收藏  举报