View Code
1 //Accepted 2665 703MS 16388K 2972 B G++ 2 #include3 #include 4 using namespace std; 5 #define M 100001 6 #define LL(x) ((x)<<1) 7 #define RR(x) ((x)<<1|1) 8 struct Seg_Tree{ 9 int left,right; 10 int mid() { 11 return (left + right) >> 1; 12 } 13 }tt[M*4]; 14 int len; 15 int sorted[M]; 16 int toLeft[20][M]; 17 int val[20][M]; 18 19 void build(int l,int r,int d,int idx) { 20 tt[idx].left = l; 21 tt[idx].right = r; 22 if(tt[idx].left == tt[idx].right) return ; 23 int mid = tt[idx].mid(); 24 int lsame = mid - l + 1;//lsame表示和val_mid相等且分到左边的 25 for(int i = l ; i <= r ; i ++) { 26 if(val[d][i] < sorted[mid]) { 27 lsame --;//先假设左边的数(mid - l + 1)个都等于val_mid,然后把实际上小于val_mid的减去 28 } 29 } 30 int lpos = l; 31 int rpos = mid+1; 32 int same = 0; 33 for(int i = l ; i <= r ; i ++) { 34 if(i == l) { 35 toLeft[d][i] = 0;//toLeft[i]表示[ tt[idx].left , i ]区域里有多少个数分到左边 36 } else { 37 toLeft[d][i] = toLeft[d][i-1]; 38 } 39 if(val[d][i] < sorted[mid]) { 40 toLeft[d][i] ++; 41 val[d+1][lpos++] = val[d][i]; 42 } else if(val[d][i] > sorted[mid]) { 43 val[d+1][rpos++] = val[d][i]; 44 } else { 45 if(same < lsame) { //有lsame的数是分到左边的 46 same ++; 47 toLeft[d][i] ++; 48 val[d+1][lpos++] = val[d][i]; 49 } else { 50 val[d+1][rpos++] = val[d][i]; 51 } 52 } 53 } 54 build(l,mid,d+1,LL(idx)); 55 build(mid+1,r,d+1,RR(idx)); 56 } 57 58 int query(int l,int r,int k,int d,int idx) { 59 if(l == r) { 60 return val[d][l]; 61 } 62 int s;//s表示[ l , r ]有多少个分到左边 63 int ss;//ss表示 [tt[idx].left , l-1 ]有多少个分到左边 64 if(l == tt[idx].left) { 65 s = toLeft[d][r]; 66 ss = 0; 67 } else { 68 s = toLeft[d][r] - toLeft[d][l-1]; 69 ss = toLeft[d][l-1]; 70 } 71 if(s >= k) { //有多于k个分到左边,显然去左儿子区间找第k个 72 int newl = tt[idx].left + ss; 73 int newr = tt[idx].left + ss + s - 1;//计算出新的映射区间 74 return query(newl,newr,k,d+1,LL(idx)); 75 } else { 76 int mid = tt[idx].mid(); 77 int bb = l - tt[idx].left - ss;//bb表示 [tt[idx].left , l-1 ]有多少个分到右边 78 int b = r - l + 1 - s;//b表示 [l , r]有多少个分到右边 79 int newl = mid + bb + 1; 80 int newr = mid + bb + b; 81 return query(newl,newr,k-s,d+1,RR(idx)); 82 } 83 } 84 85 int main() { 86 int T; 87 scanf("%d",&T); 88 while(T --) { 89 int n , m; 90 scanf("%d%d",&n,&m); 91 for(int i = 1; i <= n; i++){ 92 scanf("%d",&val[0][i]); 93 sorted[i] = val[0][i]; 94 } 95 sort(sorted + 1 , sorted + n + 1); 96 build(1,n,0,1); 97 while(m --) { 98 int l,r,k; 99 scanf("%d%d%d",&l,&r,&k);100 printf("区间第K小:%d\n",query(l,r,k,0,1));101 k = r - l + 2 - k;102 printf("区间第K大:%d\n",query(l,r,k,0,1));103 }104 }105 return 0;106 }