zoukankan      html  css  js  c++  java
  • 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
    ", ans & 0x7fffffff);
    114 }
    View Code
  • 相关阅读:
    Unity中 mesh生成斜坡
    设计模式
    Go语言高级编程
    Go语言高级编程
    agentzh 的 Nginx 教程(版本 2020.03.19)
    ubuntu18安装mysql5.7并配置远程连接
    创建图库
    交点修改
    显示中文
    浅谈前端水印
  • 原文地址:https://www.cnblogs.com/cychester/p/9726477.html
Copyright © 2011-2022 走看看