标签:== algo ring 实现 ons ati 二维 algorithm bzoj
给定三个序列 $S = \left\{ s_1, s_2, ..., s_n \right\}$ , $C = \left\{ c_1, c_2, ..., c_n \right\}$ , $M = \left\{ m_1, m_2, ..., m_n \right\}$ .
对任意 $i$ , 求 $level_i = \sum_{j \ne i, 1 \le j \le n}[s_i \ge s_j][c_i \ge c_j][m_i \ge m_j]$ .
宏观上, 将第一维按照 $s$ 排序, 那么只有前面的会对后面产生贡献. 分治, 考虑前面对后面的贡献.
第二维考虑 排序 + two pointer , 第三维用树状数组.
但是发现可能后面对前面贡献.
为了特殊情况尽可能少, 我们按照三元组 $(s_i, c_i, m_i)$ 排序.
还有一种特殊情况: 相等. 处理一下就好了.
#include <cstdio> #include <cstring> #include <cstdlib> #include <cctype> #include <algorithm> using namespace std; #define F(i, a, b) for (register int i = (a); i <= (b); i++) const int N = 100005; const int K = 200005; int n, k; struct Data { int s, c, m, id; inline Data(int _s = 0, int _c = 0, int _m = 0, int _id = 0): s(_s), c(_c), m(_m), id(_id) {} friend inline bool operator < (Data A, Data B) { return A.s != B.s ? A.s < B.s : A.c != B.c ? A.c < B.c : A.m < B.m; } friend inline bool operator == (Data A, Data B) { return A.s == B.s && A.c == B.c && A.m == B.m; } }dat[N]; int tr[K]; int lev[N], cnt[N]; namespace Input { const int S = 2000000; char s[S], *h = s+S, *t = h; inline char getchr(void) { if (h == t) fread(s, 1, S, stdin), h = s; return *h++; } inline int rd(void) { int f = 1; char c = getchr(); for (; !isdigit(c); c = getchr()) if (c == ‘-‘) f = -1; int x = 0; for (; isdigit(c); c = getchr()) x = x*10+c-‘0‘; return x*f; } } using Input::rd; inline int lowbit(int i) { return i & -i; } inline void Add(int x, int w) { for (int i = x; i <= k; i += lowbit(i)) tr[i] += w; } inline int Sum(int x) { int s = 0; for (int i = x; i > 0; i -= lowbit(i)) s += tr[i]; return s; } void Solve(int L, int R) { if (L == R) return; int M = (L+R)>>1; Solve(L, M); Solve(M+1, R); for (int cL = L-1, cR = M+1; cR <= R; cR++) { while (cL+1 <= M && dat[cR].c >= dat[cL+1].c) Add(dat[++cL].m, 1); lev[dat[cR].id] += Sum(dat[cR].m); } F(cL, L, M) if (dat[R].c >= dat[cL].c) Add(dat[cL].m, -1); else break; static Data tmp[N]; for (int tot = L, cL = L, cR = M+1; tot <= R; tot++) if (cR > R || (cL <= M && dat[cL].c <= dat[cR].c)) tmp[tot] = dat[cL++]; else tmp[tot] = dat[cR++]; F(i, L, R) dat[i] = tmp[i]; } int main(void) { #ifndef ONLINE_JUDGE freopen("xsy3262.in", "r", stdin); freopen("xsy3262.out", "w", stdout); #endif n = rd(), k = rd(); F(i, 1, n) { int s = rd(), c = rd(), m = rd(); dat[i] = Data(s, c, m, i); } sort(dat+1, dat+n+1); for (int l = 1, r; l <= n; l = r+1) { for (r = l-1; r+1 <= n && dat[r+1] == dat[l]; r++); for (int i = l, cnt = r-l; i <= r; i++, cnt--) lev[dat[i].id] += cnt; } Solve(1, n); F(i, 1, n) cnt[lev[i]]++; for (int i = 0; i < n; i++) printf("%d\n", cnt[i]); return 0; }
标签:== algo ring 实现 ons ati 二维 algorithm bzoj
原文地址:http://www.cnblogs.com/Sdchr/p/7251812.html