首页 > 代码库 > bzoj3262 陌上花开
bzoj3262 陌上花开
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3262
【题解】
cdq分治。
这题是三维偏序问题。我们先对整体排序,合并相同的,记原来的n为N,剩下的个数为n。
然后对于b排序,把a重新编号为1...n
cdq分治的时候呢,我们定义过程solve(l,r)表示解决p[l...r]的问题。
我们用mid把p[l...r]分成两个子区间p[l...mid],p[mid+1...r],其中每个子区间的a都属于这个区间,比如p[l...mid]的a就属于[l,mid]
并且每个b都单调递增。
然后我们处理前面的操作对于后面的影响。
由于两个都具有单调性,用类似于two-pointers的思想,扫描一个,另一个单调往上,在树状数组上的c位置加值,最后对于每个在树状数组上统计即可。
然后撤销操作,并且继续分治下去即可。
# include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 5e5 + 10; const int mod = 1e9+7; # define RG register # define ST static int n, K, ans[M], N; struct pa { int a, b, c, s, ans; pa() {} pa(int a, int b, int c) : a(a), b(b), c(c) {} friend bool operator <(pa a, pa b) { return a.a < b.a || (a.a == b.a && a.b < b.b) || (a.a == b.a && a.b == b.b && a.c < b.c); } friend bool operator ==(pa a, pa b) { return a.a == b.a && a.b == b.b && a.c == b.c; } }t[M], p[M]; int pn = 0; inline bool cmp(pa a, pa b) { return a.b < b.b || (a.b == b.b && a.c < b.c) || (a.b == b.b && a.a == b.a && a.c < b.c); } struct BIT { int c[M<<1], n; # define lb(x) (x&(-x)) inline void set(int _n) { n = _n; memset(c, 0, sizeof c); } inline void edt(int x, int d) { for (; x<=n; x+=lb(x)) c[x] += d; } inline int sum(int x) { int ret = 0; for (; x; x-=lb(x)) ret += c[x]; return ret; } }T; inline void solve(int l, int r) { if(l == r) { p[l].ans += p[l].s-1; return ; } int mid = l+r>>1, t1n = l-1, t2n = mid; for (int i=l; i<=r; ++i) { if(p[i].a <= mid) t[++t1n] = p[i]; else t[++t2n] = p[i]; } for (int i=l; i<=r; ++i) p[i] = t[i]; int j = l; for (int i=mid+1; i<=r; ++i) { for(; j <= mid && p[j].b <= p[i].b; ++j) T.edt(p[j].c, p[j].s); p[i].ans += T.sum(p[i].c); } for (int i=l; i<j; ++i) T.edt(p[i].c, -p[i].s); solve(l, mid); solve(mid+1, r); } int main() { cin >> n >> K; T.set(K); N = n; for (int i=1; i<=n; ++i) { scanf("%d%d%d", &t[i].a, &t[i].b, &t[i].c); t[i].s = 1; } sort(t+1, t+n+1); p[++pn] = t[1]; for (int i=2; i<=n; ++i) if(!(t[i] == t[i-1])) p[++pn] = t[i]; else p[pn].s ++; n = pn; for (int i=1; i<=n; ++i) p[i].a = i; sort(p+1, p+n+1, cmp); solve(1, n); for (int i=1; i<=n; ++i) ans[p[i].ans] += p[i].s; for (int i=0; i<=N-1; ++i) printf("%d\n", ans[i]); return 0; }
bzoj3262 陌上花开
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。