队友想的这题,T掉了,其实他们当时已经讨论状态压缩了,然而我一直在怼A,没有来想C,如果继续往状态压缩方向想的话,应该是算道水题= =,我还是太菜。补题的时候遇到一些问题,我没仔细读题,重边中不同的边算不同的方案,然后样例里又没重边,问了aols以后才找到错误,还有就是在加边的时候,要从大到小枚举状态,因为要保证每次加的dp[s^t]是加这条边之前的方案数,而删边的时候又要从小到大枚举状态,因为要大的减小的状态,这个方案数要是加边之后的。
#include<cstdio>
#include<cstring>
const int mod=1e9+7;
int n,m;
int lnk[11][11],ans[10];
int dp[1<<10],len[1<<10];
char opt[2],ch[10];
inline int read()
{
int x=0;char ch=getchar();
while(ch<'0' || ch>'9') ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}
inline void prework()
{
n=read();m=read();
memset(dp,0,sizeof(dp));
memset(lnk,0,sizeof(lnk));
}
inline void mainwork()
{
int u,v,s,t;
dp[0]=1;memset(ans,0,sizeof(ans));
for(int i=1;i<=m;i++)
{
scanf("%s",opt);
u=read();v=read();
t=(1<<(u-1))|(1<<(v-1));
if(opt[0]=='+')
{
for(s=(1<<n)-1;s>=1;s--)
if((s|t)==s && len[s]%2==0)
dp[s]=(dp[s]+dp[s^t])%mod;
lnk[u][v]++;lnk[v][u]++;
}
else
{
for(s=1;s<(1<<n);s++)
if((s|t)==s && len[s]%2==0)
dp[s]=(dp[s]-dp[s^t]+mod)%mod;
lnk[u][v]--;lnk[v][u]--;
}
for(int i=1;i<=5;i++)
ans[i]=0;
for(s=1;s<(1<<n);s++)
ans[len[s]/2]=(ans[len[s]/2]+dp[s])%mod;
for(int i=1;i<=n/2-1;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[n/2]);
}
}
int main()
{
int t;
t=read();
for(int i=0;i<(1<<10);i++)
for(int j=1;j<=10;j++)
if(i&(1<<(j-1)))
len[i]++;
for(int i=1;i<=t;i++)
{
prework();
mainwork();
}
return 0;
}