Description
Input
Output
容斥并用hash判断、保存状态,类似bzoj2012
#include<cstdio> int read(){ int x=0,c=getchar(); while(c>57||c<48)c=getchar(); while(c>47&&c<58)x=x*10+c-48,c=getchar(); return x; } int n,k; int w[64],x[6],x0[6]; int K[][7]={ {1,0,0,0,0,0,0}, {-6,1,0,0,0,0,0}, {15,-5,1,0,0,0,0}, {-20,10,-4,1,0,0,0}, {15,-10,6,-3,1,0,0}, {-6,5,-4,3,-2,1,0}, {1,-1,1,-1,1,-1,1} }; typedef unsigned long long u64; const int P=13999133; u64 xs[P],ans=0; int ys[P]; int&get(u64 x){ int w=x%P; while(xs[w]){ if(xs[w]==x)return ys[w]; w+=1234577; if(w>=P)w-=P; } xs[w]=x; return ys[w]; } u64 hash(){ u64 v=0; for(int i=0;i<6;i++)v=v*999911657+x[i]; return v; } int main(){ n=read();k=6-read(); for(int i=1;i<64;i++)w[i]=w[i>>1]+(i&1); for(int i=0;i<n;i++){ for(int j=0;j<6;j++)x0[j]=x[j]=read()+1; for(int j=0;j<64;j++)if(w[j]<=k){ for(int a=0;a<6;a++)if(j>>a&1)x[a]=0; ans+=K[k][w[j]]*get(hash())++; for(int a=0;a<6;a++)x[a]=x0[a]; } } printf("%llu",ans); return 0; }