cychester

BZOJ 1227 [SDOI2009]虔诚的墓主人 - 扫描线

Solution

离散化 扫描线, 并用 $rest[i]$ 和 $cnt[i]$ 记录 第$i$列 总共有 $cnt[i]$棵常青树, 还有$rest[i]$ 没有被扫描到。

那么 第$i$ 列的方案数 为 $C(rest[i], k) * C(cnt[i]-rest[i], k)$。 乘上行上的方案数 并加入答案。

 

需要注意组合数要预处理, 我直接算发现$k > 2$就会WA。

Code

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<vector>
  5 #define rd read()
  6 #define R register
  7 using namespace std;
  8 
  9 const int N = 2e5 + 5;
 10 
 11 int cnt[N], sum[N], n, r, l, k, rest[N];
 12 int vis[11], ans;
 13 int tot_x, tot_y, X[N], Y[N], c[N][15];
 14 
 15 struct node {
 16     int x, y;
 17 }pt[N];
 18 
 19 vector<node> q[N];
 20 
 21 inline int read() {
 22     R int X = 0, p = 1; char c = getchar();
 23     for (; c > '9' || c < '0'; c = getchar())
 24         if (c == '-') p = -1;
 25     for (; c >= '0' && c <= '9'; c = getchar())
 26         X = X * 10 + c - '0';
 27     return X * p;
 28 }
 29 
 30 inline int lowbit(int x) {
 31     return x & -x;
 32 }
 33 
 34 inline void add(R int x, int d) {
 35     for (;x <= tot_x; x += lowbit(x))
 36         sum[x] += d;
 37 }
 38 
 39 inline int query(R int x) {
 40     int re = 0;
 41     for (; x; x -= lowbit(x))
 42         re += sum[x];
 43     return re;
 44 }
 45 
 46 inline int fd_x(R int x) {
 47     return lower_bound(X + 1, X + 1 + tot_x, x) - X;
 48 }
 49 
 50 inline int fd_y(R int y) {
 51     return lower_bound(Y + 1, Y + 1 + tot_y, y) - Y;
 52 }
 53 
 54 inline int cmp(const node &A, const node &B) {
 55     return A.y == B.y ? A.x < B.x : A.y < B.y;
 56 }
 57 
 58 inline int C(int x) {
 59     return c[x][k];
 60 }
 61 
 62 int work(int x) {
 63     int len = q[x].size(), re = 0;
 64     for (R int j = k - 1; j <= len - k - 1; ++j) {
 65         int L = q[x][j].x, r = q[x][j + 1].x;
 66         int tmp = query(r - 1) - query(L);
 67         re += tmp * C(j + 1) * C(len - j - 1);
 68     }
 69     for (R int j = 0; j < len; ++j) {
 70         int tmp = C(rest[q[x][j].x]) * C(cnt[q[x][j].x] - rest[q[x][j].x]);
 71         add(q[x][j].x, -tmp);
 72         rest[q[x][j].x]--;
 73         tmp = C(rest[q[x][j].x]) * C(cnt[q[x][j].x] - rest[q[x][j].x]);
 74         add(q[x][j].x, tmp);
 75     }
 76     return re;
 77 }
 78 
 79 void init() {
 80     c[0][0] = 1;
 81     for (int i = 1; i <= n; ++i) {
 82         c[i][0] = 1;
 83         for (int j = 1; j <= min(k, i); ++j)
 84             c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
 85     }
 86 }
 87 
 88 int main()
 89 {
 90     r = rd, l = rd; n = rd;
 91     for (R int i = 1; i <= n; ++i) {
 92         pt[i].x = rd, pt[i].y = rd;
 93         X[++tot_x] = pt[i].x;
 94         Y[++tot_y] = pt[i].y;
 95     }
 96     k = rd;
 97     init();
 98     sort(X + 1, X + 1 + tot_x);
 99     sort(Y + 1, Y + 1 + tot_y);
100     tot_x = unique(X + 1, X + 1 + tot_x) - X - 1;
101     tot_y = unique(Y + 1, Y + 1 + tot_y) - Y - 1;
102     sort(pt + 1, pt + 1 + n, cmp);
103     for (R int i = 1; i <= n; ++i) {
104         pt[i].x = fd_x(pt[i].x);
105         pt[i].y = fd_y(pt[i].y);
106         cnt[pt[i].x]++;
107         q[pt[i].y].push_back(pt[i]);
108     }
109     for (R int i = 1; i <= tot_x; ++i)
110         rest[i] = cnt[i];
111     for (R int i = 1; i <= tot_y; ++i)
112         ans += work(i);
113     printf("%d\n", ans & 0x7fffffff);
114 }
View Code

 

posted on 2018-09-29 20:02  cychester  阅读(131)  评论(0编辑  收藏  举报

导航