bzoj 1227 [SDOI2009]虔诚的墓主人
疯狂re 换了一种写法才过。。。
思路:将x轴离散化,处理出来每个点上下左右一个有多少个点, 对于同一行的两个点来说,他们之间的
这些空的点都是可以一起算的,我们用树状数组按y轴从小到大维护 每一列的贡献和。。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int,int> #define piii pair<int, pair<int,int> > using namespace std; const int N = 1e5 + 10; const int M = 1e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-6; int x[N], y[N], tot1, tot2, n, m, w, k,f[N][11], sum[N]; struct Bit { int a[N]; void modify(int x, int v) { for(int i = x; i <= tot1; i += i & -i) { a[i] += v; } } int sum(int x) { int ans = 0; for(int i = x; i; i -= i & -i) { ans += a[i]; } return ans; } int query(int l, int r) { r = min(tot1, r); if(l > r) return 0; return sum(r) - sum(l - 1); } }bit; struct Point { Point(int x = 0, int y = 0) { this -> x = x; this -> y = y; } int x, y, l, r, u, d; bool operator < (const Point &rhs) const { if(y == rhs.y) return x < rhs.x; return y < rhs.y; } }p[N]; vector<Point> v[N]; int C(int a, int b) { return f[a][b]; } void init() { p[0].y = -1; p[w + 1].y = -1; for(int i = 0; i < N; i++) { for(int j = 0; j <= 10 && j <= i; j++) { if(!j || j == i) f[i][j] = 1; else f[i][j] = f[i - 1][j] + f[i - 1][j - 1]; } } } int main() { scanf("%d%d%d", &n, &m, &w); init(); for(int i = 1; i <= w; i++) { scanf("%d%d", &p[i].x, &p[i].y); x[++tot1] = p[i].x; y[++tot2] = p[i].y; } scanf("%d", &k); sort(x + 1, x + tot1 + 1); tot1 = unique(x + 1, x + tot1 + 1) - x - 1; sort(y + 1, y + tot2 + 1); tot2 = unique(y + 1, y + tot2 + 1) - y - 1; sort(p + 1, p + w + 1); for(int i = 1; i <= w; i++) p[i].x = lower_bound(x + 1, x + tot1 + 1, p[i].x) - x; int ans = 0, tmp = 0; for(int i = 1; i <= w; i++) { if(p[i].y == p[i -1].y) tmp++; else tmp = 1; p[i].l = tmp; sum[p[i].x]++; p[i].u = sum[p[i].x]; } tmp = 0; for(int i = w; i >= 1; i--) { if(p[i].y == p[i + 1].y) tmp++; else tmp = 1; p[i].r = tmp; p[i].d = sum[p[i].x] - p[i].u; } for(int i = 1; i <= w; i++) { bit.modify(p[i].x, C(p[i].u, k) * C(p[i].d, k) - bit.query(p[i].x, p[i].x)); if(i > 1 && p[i].y == p[i - 1].y) ans += C(p[i - 1].l, k) * C(p[i].r, k) * bit.query(p[i - 1].x + 1, p[i].x - 1); } printf("%d\n", ans & 2147483647); return 0; } /* */