[BZOJ3198][SDOI2013]Spring(容斥+Hash)
2018-10-17 18:27
225 查看
给定n个六元数,问有多少对数有m元对应相等。
考虑“有多少对数至少m元对应相等”的求法,显然枚举相等的位置,在这些位置上Hash统计即可。
容斥定理:至少有k个的-C(k+1,k)* 至少有k+1个的+C(k+2,k) *至少有k+2个的…=恰好有k个的。
按上式容斥,问题得解。
#include<cstdio> #include<cstring> #include<algorithm> #define rep(i,l,r) for (int i=(l); i<=(r); i++) typedef long long ll; using namespace std; const int N=100010,mod1=131,mod2=1e6+33; int n,m,cnt,a [7],C[7][7],h[mod2+10],to ,nxt ; ll ans,sm ; bool chk(int x,int y,int k){ rep(i,1,6) if (k&(1<<(i-1)) && a[x][i]!=a[y][i]) return 0; return 1; } ll calc(int S){ ll res=0; cnt=0; memset(h,0,sizeof(h)); rep(i,1,n){ ll x=0; int p=0; rep(j,1,6) if (S&(1<<(j-1))) x=(x*mod1+a[i][j])%mod2; for (p=h[x]; p; p=nxt[p]) if (chk(to[p],i,S)) { res+=sm[p]; sm[p]++; break; } if (!p) to[++cnt]=i,sm[cnt]=1,nxt[cnt]=h[x],h[x]=cnt; } return res; } int main(){ freopen("bzoj3198.in","r",stdin); freopen("bzoj3198.out","w",stdout); scanf("%d%d",&n,&m); rep(i,1,n) rep(j,1,6) scanf("%d",&a[i][j]); C[0][0]=1; rep(i,1,6){ C[i][0]=1; rep(j,1,i) C[i][j]=C[i-1][j-1]+C[i-1][j]; } rep(S,0,63){ int cnt=0; rep(i,0,5) if (S&(1<<i)) cnt++; if (cnt<m) continue; ll t=calc(S)*C[cnt][m]; ans+=((cnt-m)&1) ? -t : t; } printf("%lld\n",ans); return 0; }
相关文章推荐
- bzoj3198[Sdoi2013]spring 容斥+hash
- bzoj 3198 [Sdoi2013]spring(容斥原理+Hash)
- 【SDOI2013】【BZOJ3198】spring
- bzoj 3198: [Sdoi2013]spring 题解
- bzoj3198 [sdoi2013] spring 哈希挂表+容斥
- [BZOJ 3198] [Sdoi2013] spring 【容斥 + Hash】
- bzoj 3198: [Sdoi2013]spring (hash+容斥原理)
- BZOJ 3198([Sdoi2013]spring-Hash判重+容斥原理)
- BZOJ 3198 SDOI2013 spring
- bzoj3198 [Sdoi2013]spring 哈希表+容斥
- [BZOJ3198][Sdoi2013]spring(容斥原理+Hash)
- BZOJ 3198: [Sdoi2013]spring [容斥原理 哈希表]
- bzoj3198【SDOI2013】spring
- [BZOJ3198][Sdoi2013]spring(hash+容斥原理+组合数学)
- 3198: [Sdoi2013]spring【容斥原理+hash】
- bzoj 3198: [Sdoi2013]spring hash+容斥原理
- BZOJ 3198 Sdoi2013 spring Hash+容斥原理
- BZOJ3130 [Sdoi2013]费用流
- bzoj3130【SDOI2013】费用流
- [BZOJ3130][SDOI2013]费用流