[BZOJ 1227] 虔诚的墓主人

来源:互联网 发布:java 接口文档编写 编辑:程序博客网 时间:2024/04/30 21:16

这里写图片描述

题解:长这样的题好像都有固定套路…所有点按坐标排序、处理组合数,然后用树状数组维护奇怪的信息…….编不下去了 黄学长的题解

AC Code:

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;inline void read(int &x){x=0;char c;while((c=getchar())<'0'||c>'9');for(x=c-'0';(c=getchar())>='0'&&c<='9';x=x*10+c-'0');}const int mo = 2147483647;const int N = 100010 ;int C[N][11], w, k;void init_Calc(){    C[0][0] = 1;    for (int i = 1; i <= w; ++i)    {        C[i][0] = 1;        for (int j = 1; j <= k; ++j)            C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) & mo;    }}struct Data{    int x, y;    inline bool operator < (const Data & b) const     {        return y < b.y || (y == b.y && x < b.x);    }}p[N];int TX[N], TY[N], cX, cY;int Cnt[N], down[N], left[N], right[N];namespace BIT{    int c[N];    inline void add(int p, int v)    {        while (p <= cX) c[p] += v, p += p & -p;    }    inline int ask(int p)    {        int ret = c[p];        while (p -= p & -p) ret += c[p];        return ret;    }}int main(){    read(w), read(w), read(w);    for (int i = 1; i <= w; ++i)    {        read(p[i].x), read(p[i].y);        TX[i] = p[i].x, TY[i] = p[i].y;    }    read(k);    init_Calc();    sort(TX + 1, TX + w + 1);    cX = unique(TX + 1, TX + w + 1) - TX - 1;    sort(TY + 1, TY + w + 1);    cY = unique(TY + 1, TY + w + 1) - TY - 1;    sort(p + 1, p + w + 1);    for (int i = 1; i <= w; ++i)    {        p[i].x = lower_bound(TX + 1, TX + cX + 1, p[i].x) - TX;        p[i].y = lower_bound(TY + 1, TY + cY + 1, p[i].y) - TY;        left[i] = (p[i].y == p[i - 1].y ? left[i - 1] + 1 : 1);        Cnt[p[i].x]++;    }    for (int i = w; i; --i)         right[i] = (p[i].y == p[i + 1].y ? right[i + 1] + 1 : 1);    using namespace BIT;    int ans = 0, i = 1;    p[w + 1].y = -1;    while (i <= w)    {        int l = i;        while (p[l].y == p[l + 1].y)        {            ans += C[left[l]][k] * C[right[l + 1]][k] * (ask(p[l + 1].x - 1) - ask(p[l].x));            l++;        }        while (i <= l)        {            int x = p[i].x;            add(x, C[down[x] + 1][k] * C[Cnt[x] - down[x] - 1][k] - C[down[x]][k] * C[Cnt[x] - down[x]][k]);            down[x]++, i++;        }    }    printf("%d\n", ans & mo);    return 0;}
0 0
原创粉丝点击