# bzoj 1227 SDOI2009 虔诚的墓主人

思路还是蛮清晰的

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 100100
using 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; }

{
while (now <= linenum)
{
while (t[now] > yu) t[now] -= yu;
now += lowbit(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
{
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);
}

posted @ 2014-10-04 09:22  handsomeJian  阅读(185)  评论(0编辑  收藏