bzoj 1227 虔诚的墓主人

题目大意:

一个网格图上 有些点被染色了

求所有白点对答案的贡献 是指以这个白点为中心的十字架的数目 一个十字架可以看成中间是白点,墓地的正上、正下、正左、正右都有恰好k 棵黑点

思路:

先离线 对于每个点 对答案的贡献为C (正上黑点数,k) *C (正下黑点数,k) *C (正左黑点数,k) *C (正右黑点数,k) 

正下和正上非常好做 考虑如何快速维护正左和正右

对于竖着的空的一段 问题转化为 C (正上黑点数,k) *C (正下黑点数,k) * sigma ( C (正左黑点数,k) *C (正右黑点数,k) ) 

使用树状数组维护每一行的 C 左 * C 右 快速查询

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #define inf 2139062143
10 #define ll long long
11 #define MAXN 200100 
12 #define MOD 10000007
13 using namespace std;
14 inline int read()
15 {
16     int x=0,f=1;char ch=getchar();
17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
19     return x*f;
20 }
21 int n,m,w,k,nx,ny,x[MAXN],y[MAXN],c[MAXN][12];
22 int cntx[MAXN],cnty[MAXN],pos[MAXN],ans;
23 struct node {int x,y;}g[MAXN];
24 bool cmp(node a,node b) {return a.x<b.x||(a.x==b.x&&a.y<b.y);}
25 struct Fenwick
26 {
27     int c[MAXN];
28     inline int lowbit(int x) {return x&(-x);}
29     inline void mdf(int x,int val) {for(;x<=w;x+=lowbit(x)) c[x]+=val;}
30     inline int query(int x) {int res=0;for(;x;x-=lowbit(x)) res+=c[x];return res;}
31 }res;
32 int main()
33 {
34     n=read(),m=read(),w=read();
35     for(int i=c[0][0]=1;i<=w;i++)
36         for(int j=c[i][0]=1;j<=i&&j<=10;j++) c[i][j]=c[i-1][j-1]+c[i-1][j];
37     for(int i=0;i<=w;i++) c[i][0]=0;
38     for(int i=1;i<=w;i++) g[i].x=x[i]=read(),g[i].y=y[i]=read();k=read();
39     sort(x+1,x+w+1);nx=unique(x+1,x+w+1)-x-1;
40     for(int i=1;i<=w;i++) g[i].x=lower_bound(x+1,x+nx+1,g[i].x)-x,cntx[g[i].x]++;
41     sort(y+1,y+w+1);ny=unique(y+1,y+w+1)-y-1;
42     for(int i=1;i<=w;i++) g[i].y=lower_bound(y+1,y+ny+1,g[i].y)-y,cnty[g[i].y]++;
43     sort(g+1,g+w+1,cmp);int a,b;
44     for(int i=1,tmp=1;i<=w;i++)
45     {
46         if(g[i-1].x==g[i].x)
47             a=res.query(g[i].y-1)-res.query(g[i-1].y),
48             ans+=c[cntx[g[i].x]-(i-tmp)][k]*c[i-tmp][k]*a;
49         else tmp=i;
50         a=c[pos[g[i].y]][k]*c[cnty[g[i].y]-pos[g[i].y]][k];
51         b=c[++pos[g[i].y]][k]*c[cnty[g[i].y]-pos[g[i].y]][k];
52         res.mdf(g[i].y,-a);res.mdf(g[i].y,b);
53     }
54     printf("%d\n",ans&2147483647);
55 }
View Code

 

posted @ 2018-10-29 12:46  jack_yyc  阅读(179)  评论(0编辑  收藏  举报