Codeforces Round #433 (Div. 1, based on Olympiad of Metropolises) C. Boredom 主席樹


鏈接:

codeforces.com/contest/853/problem/C

題意:

給你一個區域內上n個點,每次查詢一個矩形區域,問有多少對點的連線經過這個矩形

題解:

把整個區域分為9個部分

1 2 3 

4 5 6

7 8 9

查詢的區域即為5,這樣估計都能看出來結果了

查詢每一個小的區域有多少個點用主席樹就可以了,主席樹的一個重要用途就是求區間[l, r]中的值介於[x,y]的值。

代碼:

31 struct Node { int l, r, sum; };
32 int n, q;
33 Node T[MAXN * 40];
34 int root[MAXN], cnt;
35 
36 void update(int l, int r, int &x, int y, int pos) {
37     T[++cnt] = T[y], T[cnt].sum++, x = cnt;
38     if (l == r) return;
39     int m = (l + r) >> 1;
40     if (pos <= m) update(l, m, T[x].l, T[y].l, pos);
41     else update(m + 1, r, T[x].r, T[y].r, pos);
42 }
43 
44 int query(int l, int r, int R, int L, int D, int U) {
45     if (D > U) return 0;
46     if (D <= l && r <= U) return T[R].sum - T[L].sum;
47     int m = (l + r) >> 1, ret = 0;
48     if (D <= m) ret += query(l, m, T[R].l, T[L].l, D, U);
49     if (U > m) ret += query(m + 1, r, T[R].r, T[L].r, D, U);
50     return ret;
51 }
52 
53 int main() {
54     ios::sync_with_stdio(false), cin.tie(0);
55     cin >> n >> q;
56     rep(i, 1, n + 1) {
57         int x;
58         cin >> x;
59         update(1, n, root[i], root[i - 1], x);
60     }
61     while (q--) {
62         int l, d, r, u;
63         cin >> l >> d >> r >> u;
64         ll cnt1 = query(1, n, root[l - 1], root[0], u + 1, n);
65         ll cnt2 = query(1, n, root[r], root[l - 1], u + 1, n);
66         ll cnt3 = query(1, n, root[n], root[r], u + 1, n);
67         ll cnt4 = query(1, n, root[l - 1], root[0], d, u);
68         ll cnt5 = query(1, n, root[r], root[l - 1], d, u);
69         ll cnt6 = query(1, n, root[n], root[r], d, u);
70         ll cnt7 = query(1, n, root[l - 1], root[0], 1, d - 1);
71         ll cnt8 = query(1, n, root[r], root[l - 1], 1, d - 1);
72         ll cnt9 = query(1, n, root[n], root[r], 1, d - 1);
73         ll ans = 0;
74         ans += cnt1*(cnt5 + cnt6 + cnt8 + cnt9);
75         ans += cnt2*(cnt4 + cnt5 + cnt6 + cnt7 + cnt8 + cnt9);
76         ans += cnt3*(cnt4 + cnt5 + cnt7 + cnt8);
77         ans += cnt4*(cnt2 + cnt3 + cnt5 + cnt6 + cnt8 + cnt9);
78         ans += cnt5*(n - 1);
79         ans += cnt6*(cnt1 + cnt2 + cnt4 + cnt5 + cnt7 + cnt8);
80         ans += cnt7*(cnt2 + cnt3 + cnt5 + cnt6);
81         ans += cnt8*(cnt1 + cnt2 + cnt3 + cnt4 + cnt5 + cnt6);
82         ans += cnt9*(cnt1 + cnt2 + cnt4 + cnt5);
83         cout << ans / 2 << endl;
84     }
85     return 0;
86 }

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com