又是一道主席树模板题,注意数组从0开始,还有主席树耗费空间很大,数组开大点,之前开小了莫名其妙TLE。QAQ
——代码
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define ls son[now][0], l, mid 5 #define rs son[now][1], mid + 1, r 6 7 using namespace std; 8 9 const int N = 100005; 10 11 int T, n, m, sz, tot, ans; 12 int a[N], b[N], rt[N], son[10 * N][2], sum[10 * N]; 13 14 inline void build(int &now, int l, int r) 15 { 16 now = ++tot; 17 sum[now] = 0; 18 if(l == r) return; 19 int mid = (l + r) >> 1; 20 build(ls); 21 build(rs); 22 } 23 24 inline void update(int &now, int l, int r, int last, int x) 25 { 26 now = ++tot; 27 son[now][0] = son[last][0]; 28 son[now][1] = son[last][1]; 29 sum[now] = sum[last] + 1; 30 if(l == r) return; 31 int mid = (l + r) >> 1; 32 if(x <= mid) update(ls, son[now][0], x); 33 else update(rs, son[now][1], x); 34 } 35 36 inline void query(int s, int t, int l, int r, int x) 37 { 38 if(l == r) 39 { 40 ans += sum[t] - sum[s]; 41 return; 42 } 43 int mid = (l + r) >> 1; 44 if(x <= mid) query(son[s][0], son[t][0], l, mid, x); 45 else 46 { 47 ans += sum[son[t][0]] - sum[son[s][0]]; 48 query(son[s][1], son[t][1], mid + 1, r, x); 49 } 50 } 51 52 inline void clear() 53 { 54 n = m = sz = tot = 0; 55 memset(a, 0, sizeof(a)); 56 memset(b, 0, sizeof(b)); 57 memset(sum, 0, sizeof(sum)); 58 memset(son, 0, sizeof(son)); 59 memset(rt, 0, sizeof(rt)); 60 } 61 62 int main() 63 { 64 int i, j = 0, k, x, y, z; 65 scanf("%d", &T); 66 while(T--) 67 { 68 scanf("%d %d", &n, &m); 69 for(i = 1; i <= n; i++) scanf("%d", &a[i]), b[i] = a[i]; 70 sort(b, b + n + 1); 71 sz = unique(b + 1, b + n + 1) - (b + 1); 72 tot = 0; 73 build(rt[0], 1, sz); 74 for(i = 1; i <= n; i++) 75 { 76 k = lower_bound(b + 1, b + sz + 1, a[i]) - b; 77 update(rt[i], 1, sz, rt[i - 1], k); 78 } 79 printf("Case %d: ", ++j); 80 for(i = 1; i <= m; i++) 81 { 82 scanf("%d %d %d", &x, &y, &z); 83 k = upper_bound(b + 1, b + sz + 1, z) - b - 1; 84 if(k) 85 { 86 ans = 0; 87 query(rt[x], rt[y + 1], 1, sz, k); 88 printf("%d ", ans); 89 } 90 else printf("0 "); 91 } 92 } 93 return 0; 94 }