【HDOJ】4251 The Famous ICPC Team Again
划分树模板题目,主席树也可解。
划分树。
1 /* 4251 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <algorithm> 12 #include <cstdio> 13 #include <cmath> 14 #include <ctime> 15 #include <cstring> 16 #include <climits> 17 #include <cctype> 18 #include <cassert> 19 #include <functional> 20 #include <iterator> 21 #include <iomanip> 22 using namespace std; 23 //#pragma comment(linker,"/STACK:102400000,1024000") 24 25 #define sti set<int> 26 #define stpii set<pair<int, int> > 27 #define mpii map<int,int> 28 #define vi vector<int> 29 #define pii pair<int,int> 30 #define vpii vector<pair<int,int> > 31 #define rep(i, a, n) for (int i=a;i<n;++i) 32 #define per(i, a, n) for (int i=n-1;i>=a;--i) 33 #define clr clear 34 #define pb push_back 35 #define mp make_pair 36 #define fir first 37 #define sec second 38 #define all(x) (x).begin(),(x).end() 39 #define SZ(x) ((int)(x).size()) 40 #define lson l, mid, rt<<1 41 #define rson mid+1, r, rt<<1|1 42 43 const int maxn = 1e5+5; 44 int order[maxn]; 45 int toLeft[18][maxn]; 46 int val[18][maxn]; 47 int n; 48 49 void Build(int l, int r, int dep) { 50 if (l == r) { 51 toLeft[dep][l] = toLeft[dep][l-1] + 1; 52 return ; 53 } 54 55 int mid = (l + r) >> 1; 56 int same = mid - l + 1; 57 58 rep(i, l, r+1) { 59 if (val[dep][i] < order[mid]) 60 --same; 61 } 62 63 int lpos = l, rpos = mid + 1; 64 65 rep(i, l, r+1) { 66 if (val[dep][i] < order[mid]) { 67 val[dep+1][lpos++] = val[dep][i]; 68 } else if (val[dep][i]==order[mid] && same>0) { 69 val[dep+1][lpos++] = val[dep][i]; 70 --same; 71 } else { 72 val[dep+1][rpos++] = val[dep][i]; 73 } 74 toLeft[dep][i] = toLeft[dep][l-1] + lpos - l; 75 } 76 77 Build(l, mid, dep+1); 78 Build(mid+1, r, dep+1); 79 } 80 81 int Query(int l, int r, int k, int L, int R, int dep) { 82 if (l == r) { 83 return val[dep][l]; 84 } 85 86 int mid = (L + R) >> 1; 87 int tmp = toLeft[dep][r] - toLeft[dep][l-1]; 88 89 if (tmp >= k) { 90 int ll = L + toLeft[dep][l-1] - toLeft[dep][L-1]; 91 int rr = ll + tmp - 1; 92 93 return Query(ll, rr, k, L, mid, dep+1); 94 } else { 95 k -= tmp; 96 int ll = mid+1 + l-L - (toLeft[dep][l-1] - toLeft[dep][L-1]); 97 int rr = ll + (r-l+1-tmp) - 1; 98 99 return Query(ll, rr, k, mid+1, R, dep+1); 100 } 101 } 102 103 void solve() { 104 sort(order+1, order+1+n); 105 Build(1, n, 0); 106 107 int q; 108 int l, r, kth; 109 int ans; 110 111 scanf("%d", &q); 112 while (q--) { 113 scanf("%d %d", &l, &r); 114 kth = ((l+r)>>1) - l + 1; 115 ans = Query(l, r, kth, 1, n, 0); 116 printf("%d\n", ans); 117 } 118 } 119 120 int main() { 121 ios::sync_with_stdio(false); 122 #ifndef ONLINE_JUDGE 123 freopen("data.in", "r", stdin); 124 freopen("data.out", "w", stdout); 125 #endif 126 127 int t = 0; 128 129 while (scanf("%d", &n)!=EOF) { 130 rep(i, 1, n+1) { 131 scanf("%d", &val[0][i]); 132 order[i] = val[0][i]; 133 } 134 printf("Case %d:\n", ++t); 135 solve(); 136 } 137 138 #ifndef ONLINE_JUDGE 139 printf("time = %d.\n", (int)clock()); 140 #endif 141 142 return 0; 143 }
主席树。
1 /* 4251 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <algorithm> 12 #include <cstdio> 13 #include <cmath> 14 #include <ctime> 15 #include <cstring> 16 #include <climits> 17 #include <cctype> 18 #include <cassert> 19 #include <functional> 20 #include <iterator> 21 #include <iomanip> 22 using namespace std; 23 //#pragma comment(linker,"/STACK:102400000,1024000") 24 25 #define sti set<int> 26 #define stpii set<pair<int, int> > 27 #define mpii map<int,int> 28 #define vi vector<int> 29 #define pii pair<int,int> 30 #define vpii vector<pair<int,int> > 31 #define rep(i, a, n) for (int i=a;i<n;++i) 32 #define per(i, a, n) for (int i=n-1;i>=a;--i) 33 #define clr clear 34 #define pb push_back 35 #define mp make_pair 36 #define fir first 37 #define sec second 38 #define all(x) (x).begin(),(x).end() 39 #define SZ(x) ((int)(x).size()) 40 // #define lson l, mid, rt<<1 41 // #define rson mid+1, r, rt<<1|1 42 43 const int maxn = 1e5+5; 44 const int maxm = maxn * 20; 45 int a[maxn], b[maxn]; 46 int T[maxn]; 47 int lson[maxm], rson[maxm], c[maxm]; 48 int n, m, tot; 49 50 void init() { 51 m = tot = 0; 52 } 53 54 int Build(int l, int r) { 55 int rt = tot++; 56 57 c[rt] = 0; 58 if (l == r) 59 return rt; 60 61 int mid = (l + r) >> 1; 62 63 lson[rt] = Build(l, mid); 64 rson[rt] = Build(mid+1, r); 65 return rt; 66 } 67 68 int Insert(int rt, int p, int delta) { 69 int nrt = tot++, ret = nrt; 70 int l = 0, r = m - 1, mid; 71 72 c[nrt] = c[rt] + delta; 73 while (l < r) { 74 mid = (l + r) >> 1; 75 if (p <= mid) { 76 lson[nrt] = tot++; 77 rson[nrt] = rson[rt]; 78 nrt = lson[nrt]; 79 rt = lson[rt]; 80 r = mid; 81 } else { 82 lson[nrt] = lson[rt]; 83 rson[nrt] = tot++; 84 nrt = rson[nrt]; 85 rt = rson[rt]; 86 l = mid + 1; 87 } 88 c[nrt] = c[rt] + delta; 89 } 90 91 return ret; 92 } 93 94 int Query(int lrt, int rrt, int k, int l, int r) { 95 if (l == r) 96 return l; 97 98 int mid = (l + r) >> 1; 99 int tmp = c[lson[rrt]] - c[lson[lrt]]; 100 101 if (tmp >= k) { 102 return Query(lson[lrt], lson[rrt], k, l, mid); 103 } else { 104 k -= tmp; 105 return Query(rson[lrt], rson[rrt], k, mid+1, r); 106 } 107 } 108 109 void solve() { 110 init(); 111 sort(b, b+n); 112 m = unique(b, b+n) - b; 113 T[0] = Build(0, m-1); 114 rep(i, 0, n) { 115 int id = lower_bound(b, b+m, a[i]) - b; 116 T[i+1] = Insert(T[i], id, 1); 117 } 118 119 int q; 120 int l, r, kth; 121 int ans; 122 123 scanf("%d", &q); 124 while (q--) { 125 scanf("%d %d", &l, &r); 126 kth = ((l+r)>>1)-l+1; 127 int id = Query(T[l-1], T[r], kth, 0, m-1); 128 ans = b[id]; 129 printf("%d\n", ans); 130 } 131 } 132 133 int main() { 134 ios::sync_with_stdio(false); 135 #ifndef ONLINE_JUDGE 136 freopen("data.in", "r", stdin); 137 freopen("data.out", "w", stdout); 138 #endif 139 140 int t = 0; 141 142 while (scanf("%d", &n)!=EOF) { 143 rep(i, 0, n) { 144 scanf("%d", &a[i]); 145 b[i] = a[i]; 146 } 147 printf("Case %d:\n", ++t); 148 solve(); 149 } 150 151 #ifndef ONLINE_JUDGE 152 printf("time = %d.\n", (int)clock()); 153 #endif 154 155 return 0; 156 }