首页 > 代码库 > bzoj 1227 SDOI2009 虔诚的墓主人

bzoj 1227 SDOI2009 虔诚的墓主人

    思路还是蛮清晰的

  ask:

      x = t[nowright-1] - t[nowleft]

  get_ans:
       ans += C(l[nowleft],k) * C(r[nowright],k) * x

  update:
      t[i] = t[i] - C(up[i],k) * C(down[i],k) + C(up[i]-1,k) * C(down[i]+1,k)

  sort:
  y first
  x second

    组合数的递推公式都忘了……

    C (i, j) = C (i-1, j) + C (i-1, j-1)

    这道题模比较大,乘的时候要注意不爆 long long

    上代码:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <iostream>#include <cmath>#include <map>#define yu 2147483648LL#define N 100100using namespace std;struct sss{    int x, y;}dian[N];int n, K, linenum = 0;long long ans = 0, t[N] = {0};map <int, int> qx, qy, rank;int up[N], down[N], fan[N];long long C[N][11] = {0};bool cmp(sss a, sss b) { return a.y == b.y ? a.x < b.x : a.y < b.y; }int lowbit(int x) { return x & -x; }void add(int now, int addnum){    addnum %= yu;    while (now <= linenum)    {        t[now] += addnum;        while (t[now] > yu) t[now] -= yu;        now += lowbit(now);    }}long long ask(int now){    long long zan = 0;    while (now)    {        zan += t[now];        while (zan > yu) zan -= yu;        now -= lowbit(now);    }    return zan%yu;}void makeC(){    C[0][0] = 1;    for (int i = 1; i <= n; ++i)    {        C[i][0] = 1;        for (int j = 1; j <= min(i, K); ++j)        {            C[i][j] = C[i-1][j-1] + C[i-1][j];            while (C[i][j] > yu) C[i][j] -= yu;        }    }}void beforework(){    int xz[N]; makeC();    for (int i = 1; i <= n; ++i) xz[i] = dian[i].x;    sort(xz+1, xz+1+n); xz[0] = -1;    for (int i = 1; i <= n; ++i)        if (xz[i] != xz[i-1])        {            rank[xz[i]] = ++linenum;            fan[linenum] = xz[i];        }    for (int i = 1; i <= linenum; ++i)    { up[i] = qx[fan[i]]; down[i] = 0; }}void get_ans(){    int ybefore = -1, l, r;    long long x;    int i = 1;    while (i <= n)    {        if (dian[i].y != ybefore)        {            l = 1; r = qy[dian[i].y]-1;            ybefore = dian[i].y;            int d = rank[dian[i].x];            add(d, C[up[d]-1][K] * C[down[d]+1][K] - C[up[d]][K] * C[down[d]][K]);            up[d]--; down[d]++;        }        else        {            x = ask(rank[dian[i].x]-1) - ask(rank[dian[i-1].x]);            if (x < 0) x += yu;            ans += (((x * C[l][K])%yu) * C[r][K])%yu;            l += 1; r -= 1;            while (ans > yu) ans -= yu;            int d = rank[dian[i].x];            add(d, C[up[d]-1][K] * C[down[d]+1][K] - C[up[d]][K] * C[down[d]][K]);            up[d]--; down[d]++;        }        i++;    }}int main(){    scanf("%d%d%d", &n, &n, &n);    for (int i = 1; i <= n; ++i)    {        scanf("%d%d", &dian[i].x, &dian[i].y);        qx[dian[i].x] ++; qy[dian[i].y] ++;    }    scanf("%d", &K);    sort(dian+1, dian+1+n, cmp);    beforework();    get_ans();    printf("%I64d\n", ans%yu);}

 

bzoj 1227 SDOI2009 虔诚的墓主人