本题目的意思,就是有n个灯泡,和m个开关,每个开关控制着一些灯的明亮,求所有在2^m种选择下,所有明着的灯三次方总和,
定义xi 为第i盏灯的明亮情况0代表不明,1,代表名
X^3 = (x1 + x2 + x3 .. xn)*(x1 + x2 + x3 .. xn)*(x1 + x2 + x3 .. xn) 所以可以分开求在三盏灯为i,j,k 时所有情况个数,也就是这三盏灯对答案的贡献。
#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include <cstring> #include <map> #include <set> #include <vector> #include <cctype> #include <cmath> #include <queue> #define ls rt<<1 #define rs rt<<1|1 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define mem(a,n) memset(a,n,sizeof(a)) #define rep(i,n) for(int i=0;i<(int)n;i++) #define rep1(i,x,y) for(int i=x;i<=(int)y;i++) using namespace std; //#pragma comment(linker, "/STACK:102400000,102400000") typedef pair<int,int> pii; typedef long long ll; const int inf = 0x3f3f3f3f; const ll oo = 1e12; typedef pair<ll,ll> pll; const int mod = 1e9+7; const int N = 55; int a,b,c,n,m; int st[N][N]; bool vis[N][8]; int d[N][8]; inline int tran(int p,int s){ if(st[p][a]) s^=1; if(st[p][b]) s^=2; if(st[p][c]) s^=4; return s; } int main() { int T,kase=1; scanf("%d",&T); while(T--){ scanf("%d %d",&n,&m); memset(st,0,sizeof(st)); rep1(i,1,m){ int x,y; scanf("%d",&x); rep1(j,1,x) scanf("%d",&y),st[i][y]=1; } ll ans = 0; for(a=1;a<=n;a++) for(b=1;b<=n;b++) for(c=1;c<=n;c++){ for(int i=7;i>=0;i--) d[m+1][i]=(i==0); for(int i=m;i>=1;i--) for(int j=0;j<=7;j++) d[i][j] = (d[i+1][j]+d[i+1][tran(i,j)])%mod; ans = (ans + d[1][7])%mod; } printf("Case #%d: %d\n",kase++,(int)ans); } return 0; }