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 }