1. 程式人生 > >黑暗 - 容斥 - 組合計數

黑暗 - 容斥 - 組合計數

題目大意:平面上a個白色棋子,b個黃色,c個藍色,對每個棋子移動m步,每步可以上下左右移動1單位距離,問有多少種方案,使得任意兩點座標相同當且進當顏色相同。座標絕對值、棋子總數、步數均不超過1000。
題解:先容斥不同顏色座標不同,問題轉為一些點m步後走到同一個點的方案數,將(x,y)座標變換為(x+y,x-y),然後橫縱獨立,然後座標範圍不大,暴力列舉組合數計算即可。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long #define mod 1000000007 #define ull unsigned lint #define db long double #define pb push_back #define mp make_pair #define fir first #define sec second #define gc getchar() #define debug(x) cerr<<#x<<"="<<x #define sp <<" " #define ln <<endl using namespace std;
typedef pair<int,int> pii; typedef set<int>::iterator sit; inline int inn() { int x;scanf("%d",&x);return x; } const int N=100010;int fac[N],facinv[N],a[N]; inline int gabs(int x) { return x<0?-x:x; } inline int fast_pow(int x,int k,int ans=1) { for(;k;k>>=1,x=(lint)x*x%mod) (k&
1)?ans=(lint)ans*x%mod:0;return ans; } inline int prelude(int n) { rep(i,fac[0]=1,n) fac[i]=(lint)fac[i-1]*i%mod; facinv[n]=fast_pow(fac[n],mod-2); for(int i=n-1;i>=0;i--) facinv[i]=(i+1ll)*facinv[i+1]%mod; return 0; } inline int binom(int n,int m) { if(n<0||m<0||n<m) return 0;return (lint)fac[n]*facinv[m]%mod*facinv[n-m]%mod; } inline int calc(int *a,int n,int p,int m) { int ans=1; rep(i,1,n) { int dx=gabs(a[i]-p); if(((dx+m)%2)||dx>m) return 0; ans=(lint)ans*binom(m,(dx+m)/2)%mod; } return ans; } inline int solve(vector<int> x,int n,int m) { rep(i,1,n) a[i]=x[i];int mn=a[1],mx=a[1]; rep(i,1,n) mn=min(mn,a[i]),mx=max(mx,a[i]); lint ans=0;rep(i,mx-m,mn+m) ans+=calc(a,n,i,m); return ans%mod; } struct P{ vector<int> x,y;int n;static int m; inline int init(int _n) { n=_n,x.resize(n+1),y.resize(n+1); rep(i,1,n) x[i]=inn(),y[i]=inn(), x[i]+=y[i],y[i]=x[i]-2*y[i]; return 0; } inline P& operator=(const P &p) { x=p.x,y=p.y,n=p.n;return *this; } inline P operator+(const P &p)const { P q;q.x=x,q.y=y,q.n=n+p.n; rep(i,1,p.n) q.x.pb(p.x[i]),q.y.pb(p.y[i]); return q; } inline int F()const { return (lint)solve(x,n,m)*solve(y,n,m)%mod; } }A,B,C; int P::m=0; int main() { prelude(N-1); int n=inn(),a=inn(),b=inn(),c=n-a-b;P::m=inn(); A.init(a),B.init(b),C.init(c),a=A.F(),b=B.F(),c=C.F(); int ab=(A+B).F(),bc=(B+C).F(),ac=(A+C).F(),abc=(A+B+C).F(); lint ans=(lint)a*b%mod*c%mod-(lint)ab*c%mod-(lint)ac*b%mod-(lint)bc*a%mod+2ll*abc%mod; ans%=mod,ans+=mod,ans%=mod;return !printf("%lld\n",ans); }