1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <string> #include <set> #include <queue>
using namespace std; const int maxn = 50005; struct node{ int ls, rs, sum; }tree[maxn * 20]; int a[maxn], b[3 * maxn], rt[maxn],l[maxn], r[maxn] , k1[maxn], k2[maxn]; int tot, Sum; void build(int &o, int l, int r) { o = ++tot; tree[o].sum = 0; if(l == r) return; int mid = (l + r) >> 1; build(tree[o].ls, l , mid); build(tree[o].rs, mid + 1, r); }
void update(int &o, int last, int l, int r, int pos) { o = ++tot; tree[o].ls = tree[last].ls; tree[o].rs = tree[last].rs; tree[o].sum = tree[last].sum + 1; if(l == r) return; int mid = (l + r) >> 1; if(pos <= mid) update(tree[o].ls, tree[last].ls, l, mid, pos); else update(tree[o].rs, tree[last].rs, mid + 1, r, pos); }
void query(int o, int last, int l, int r, int left, int right) { if(left > r || right < l) return; if(left <= l && right >= r) { Sum += tree[o].sum - tree[last].sum; return; } int mid = (l + r) >> 1; query(tree[o].ls, tree[last].ls, l, mid, left, right); query(tree[o].rs, tree[last].rs, mid + 1, r, left, right); }
int main() { int T,n,Q, caser = 1; scanf("%d",&T); while(T--) { tot = 0; scanf("%d %d",&n,&Q); for(int i = 1; i <= n; ++i) { scanf("%d",&a[i]); b[i] = a[i]; } int tot1 = n; for(int i = 1; i <= Q; ++i) { scanf("%d %d %d %d",&l[i],&r[i],&k1[i],&k2[i]); b[++tot1] = k1[i] - 1; b[++tot1] = k2[i]; } sort(b + 1, b + tot1 + 1); int N = unique(b + 1, b + tot1 + 1) - (b + 1); build(rt[0], 1, N); for(int i = 1; i <= n; ++i) { a[i] = lower_bound(b + 1, b + N + 1, a[i]) - b; update(rt[i], rt[i - 1], 1, N, a[i]); } printf("Case #%d:\n",caser++); for(int i = 1; i <= Q; ++i) { Sum = 0; int v = lower_bound(b + 1, b + N + 1,k1[i] - 1) - b; query(rt[r[i]], rt[l[i] - 1], 1, N, 1, v); int num1 = Sum; v = lower_bound(b + 1, b + N + 1, k2[i]) - b; Sum = 0; query(rt[r[i]], rt[l[i] - 1], 1, N, 1, v); printf("%d\n", Sum - num1);
} } }
|