黑暗

img

题目大意

(n) 个点,每个点一定是红,绿,蓝三种颜色之一。每一个点有一个出初始坐标 $ (x_i,y_i) $ 你要让每一个点都移动 (m) 步,每一步可以沿着 (x) 轴正负方向或者沿着 $ y $ 轴正负方向移动一个单位,即 ((x,y) ightarrow{(x+1,y),(x-1,y),(x,y+1),(x,y-1)}) 使得所有同色点在相同的位置上,不同色的点在不同的位置上,求方案数量。

题解

将坐标系旋转 (45°) ,将原来的 ((x,y) ightarrow{(x+1,y),(x-1,y),(x,y+1),(x,y-1)}) 变为 ((x,y) ightarrow{(x+1,y+1),(x-1,y+1),(x+1,y-1),(x-1,y-1)}) 然后将 ((x,y))分开考虑,对于每一个确定的 $ x $ 或 $ y $ 和每一种颜色,求出所有该颜色来到这个坐标的方案数。

接着就容斥就好,答案 (=) 三种颜色集合点任意选 (-) 两个颜色在相同点另一个颜色任意选 (+ 2)三个点在相同颜色的方案数。

#include<bits/stdc++.h>
#define LL long long
#define M 3001
using namespace std;
int read(){
    int nm=0,fh=1; char cw=getchar();
    for(;!isdigit(cw);cw=getchar()) if(cw=='-') fh=-fh;
    for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
    return nm*fh;
}
#define mod 1000000007
#define bas 3020
int n,m,C[1020][1020],X[M],Y[M],A,B,px[3][bas<<1|1],py[3][bas<<1|1];
int res,L[3],R[3],sumx[3],sumy[3],CX[8][bas<<1|1],CY[8][bas<<1|1];
int dtx[4],dty[4];
inline int add(int x,int y){return (x+y>=mod)?x+y-mod:x+y;}
inline int mns(int x,int y){return (x-y<0)?x-y+mod:x-y;}
inline int mul(int x,int y){return (LL)x*(LL)y%mod;}
const int STA[]={3,5,6,7};
int main(){
	n=read(),A=read(),B=read(),m=read();
	L[0]=1,L[1]=A+1,L[2]=A+B+1;
	R[0]=A,R[1]=A+B,R[2]=n;
	for(int i=0;i<=m;i++){
		C[i][0]=1;
		for(int j=1;j<=i;j++) C[i][j]=add(C[i-1][j],C[i-1][j-1]);
	}
	for(int i=1,x,y;i<=n;i++) x=read(),y=read(),X[i]=x-y,Y[i]=x+y;
	for(int pos=0;pos<=(bas<<1);pos++) for(int k=0;k<3;k++) px[k][pos]=py[k][pos]=1;
	for(int pos=-bas;pos<=bas;pos++) for(int dis,k=0;k<3;k++){
		for(int i=L[k];i<=R[k];i++){
			dis=abs(X[i]-pos); if(dis>m||((dis^m)&1)){px[k][pos+bas]=0;break;}
			px[k][pos+bas]=mul(px[k][pos+bas],C[m][(m-dis)>>1]);
		} sumx[k]=add(px[k][pos+bas],sumx[k]);
		for(int i=L[k];i<=R[k];i++){
			dis=abs(Y[i]-pos); if(dis>m||((dis^m)&1)){py[k][pos+bas]=0;break;}
			py[k][pos+bas]=mul(py[k][pos+bas],C[m][(m-dis)>>1]);
		} sumy[k]=add(py[k][pos+bas],sumy[k]);
	}
	for(int i=0;i<=(bas<<1);i++) for(int sta=0,nowx=1,nowy=1;sta<4;sta++,nowx=nowy=1){
		for(int k=0;k<3;k++) if((STA[sta]>>k)&1) nowx=mul(nowx,px[k][i]),nowy=mul(nowy,py[k][i]);
		dtx[sta]=add(dtx[sta],nowx),dty[sta]=add(dty[sta],nowy);
	} res=mul(mul(mul(sumx[0],sumy[0]),mul(sumx[1],sumy[1])),mul(sumx[2],sumy[2]));
	res=mns(res,mul(mul(dtx[0],dty[0]),mul(sumx[2],sumy[2])));
	res=mns(res,mul(mul(dtx[1],dty[1]),mul(sumx[1],sumy[1])));
	res=mns(res,mul(mul(dtx[2],dty[2]),mul(sumx[0],sumy[0])));
	res=add(res,mul(2,mul(dtx[3],dty[3]))),printf("%d
",res); return 0;
}
原文地址:https://www.cnblogs.com/OYJason/p/10052407.html