C - Dynamic Graph Matching HDU - 6321

状压dp,先记录偶数状态,然后直接暴力转移即可。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
#include
#pragma GCC optimize(2)
#define up(i,a,b)  for(int i=a;i
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int num = 0;
int T, n, m;
int sta[5000];
int edges[5000];
ll dp[10][2000];
const int mod = 1e9 + 7;
void init()
{
	up(i, 1, (1 << 10))
	{
		int cnt = 0;
		dwd(j, 10, 0)
		{
			if (i >> j & 1)cnt++;
		}
		if (cnt % 2 == 0)
		{
			sta[num] = i;
			edges[num++] = cnt / 2;
		}
	}
}
ll ans[30004];
int main()
{
	T = read();
	init();
	while (T--)
	{
		int cur = 0;
		n = read(), m = read();
		upd(i, 0, (1 << n))dp[cur][i] = dp[cur ^ 1][i] = 0;
		dp[cur][0] = dp[cur ^ 1][0] = 1;
		int status = (1 << n) - 1;
		int u, v;
		char op[2];
		upd(p, 1, m)
		{
			scanf("%s %d %d", op, &u, &v); u--, v--;
			if (op[0] == '+')
			{
				cur = cur ^ 1;
				int temp = ((1 << u) | (1 << v));
				up(i, 0, num)
				{
					int num_s= sta[i];
					if (num_s > status)break;
					dp[cur][num_s] = dp[cur ^ 1][num_s];
					if ((temp&num_s)==temp)
					{
						dp[cur][num_s] = (dp[cur][num_s] + dp[cur ^ 1][num_s^temp]) % mod;
					}
					ans[edges[i]] = (ans[edges[i]] + dp[cur][num_s]) % mod;
				}
				upd(i, 1, n / 2)printf("%lld%s", ans[i],i==n/2?"\n":" ");
			}
			else{
				cur = cur ^ 1;
				int temp = ((1 << u) | (1 << v));
				up(i, 0, num)
				{
					int num_s = sta[i];
					if (num_s > status)break;
					dp[cur][num_s] = dp[cur ^ 1][num_s];
					if ((temp&num_s)==temp)
					{
						dp[cur][num_s] = (dp[cur][num_s] - dp[cur ^ 1][num_s^temp] + mod) % mod;
					}
					ans[edges[i]] = (ans[edges[i]] + dp[cur][num_s]) % mod;
				}
				upd(i, 1, n / 2)printf("%lld%s", ans[i], i == n / 2 ? "\n" : " ");
			}
			upd(i, 0, 10)ans[i] = 0;
		}
	}
	return 0;
}

你可能感兴趣的:(状压)