先O(n^3)的预处理,然后每次计算都是O(n)的。。。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 505;
const int mod = 1e9+7;
struct node
{
int size;
node *fa, *ch[2];
}pool[maxn], *tail, *root;
LL h[maxn];
LL dp[maxn][maxn];
queue<node*> q;
int tree, cnt, m;
node* newnode(int size, node *f)
{
tail->size = size;
tail->fa = f;
tail->ch[0] = tail->ch[1] = 0;
return tail++;
}
void init()
{
tail = pool;
root = newnode(0, NULL);
}
LL powmod(LL a, LL b)
{
LL res = 1, base = a;
while(b) {
if(b & 1) res = res * base % mod;
base = base * base % mod;
b >>= 1;
}
return res;
}
void _init()
{
h[0] = h[1] = 1;
for(int i = 2; i < maxn; i++) h[i] = h[i-1] * (4 * i - 2) % mod * powmod(i+1, mod-2) % mod;
dp[0][0] = 1;
for(int i = 1; i < maxn; i++)
for(int j = 0; j < maxn; j++)
for(int k = 0; k <= j; k++)
dp[i][j] = (dp[i][j] + dp[i-1][j-k] * h[k] % mod) % mod;
}
void dfs(node *o)
{
cnt--;
if(o->ch[0]) {
if(o->ch[0]->size) q.push(o->ch[0]);
else dfs(o->ch[0]);
}
else tree++;
if(o->ch[1]) {
if(o->ch[1]->size) q.push(o->ch[1]);
else dfs(o->ch[1]);
}
else tree++;
}
void bfs()
{
LL ans = 1;
dfs(root);
while(!q.empty()) {
node *u = q.front();
q.pop();
cnt = u->size;
tree = 0;
dfs(u);
ans = ans * dp[tree][cnt] % mod;
}
printf("%lld\n", ans);
}
void work()
{
int op, sz;
node *u = root;
for(int i = 1; i <= m; i++) {
scanf("%d", &op);
if(op == 0) u = u->fa;
if(op == 1) {
if(!u->ch[0]) u->ch[0] = newnode(0, u);
u = u->ch[0];
}
if(op == 2) {
if(!u->ch[1]) u->ch[1] = newnode(0, u);
u = u->ch[1];
}
if(op == 3) {
scanf("%d", &sz);
if(u->ch[0]) continue;
u->ch[0] = newnode(sz, u);
}
if(op == 4) {
scanf("%d", &sz);
if(u->ch[1]) continue;
u->ch[1] = newnode(sz, u);
}
}
bfs();
}
int main()
{
_init();
int _ = 0;
while(scanf("%d", &m) != EOF) {
printf("Case #%d: ", ++_);
init();
work();
}
return 0;
}