WelcometoSAO(StrangeandAbnormalOnline)。这是一个VRMMORPG,含有n个关卡。但是,挑战不同关卡的顺序是一
个很大的问题。有n–1个对于挑战关卡的限制,诸如第i个关卡必须在第j个关卡前挑战,或者完成了第k个关卡才
能挑战第l个关卡。并且,如果不考虑限制的方向性,那么在这n–1个限制的情况下,任何两个关卡都存在某种程
度的关联性。即,我们不能把所有关卡分成两个非空且不相交的子集,使得这两个子集之间没有任何限制。
标签:read comet http char ext dfs div 节点 content
对于每个数据,输出一行一个整数,为攻克关卡的顺序方案个数,mod1,000,000,007输出。
#pragma GCC optimize("O2") #include <cstdio> #include <cstring> char buf[10000000], *ptr = buf - 1; inline int readint(){ int n = 0; char ch = *++ptr; while(ch < ‘0‘ || ch > ‘9‘) ch = *++ptr; while(ch <= ‘9‘ && ch >= ‘0‘){ n = (n << 1) + (n << 3) + (ch ^ 48); ch = *++ptr; } return n; } typedef long long ll; const int maxn = 1000 + 10, mod = 1000000007; inline void add(ll &x, ll y){ x = (x + y) % mod; } ll C[maxn][maxn]; struct Edge{ int to, val, next; // (val = 1) <=> ‘>‘ ; (val = 0) <=> ‘<‘ Edge(){} Edge(int _t, int _v, int _n): to(_t), val(_v), next(_n){} }e[maxn * 2]; int fir[maxn], cnt; inline void ins(int u, int v, int w){ e[++cnt] = Edge(v, w, fir[u]); fir[u] = cnt; e[++cnt] = Edge(u, w ^ 1, fir[v]); fir[v] = cnt; } int n; ll sum[maxn][maxn]; ll f[maxn][maxn], tp[maxn]; int siz[maxn]; void dfs(int u, int fa){ siz[u] = f[u][1] = 1; for(int v, i = fir[u]; i; i = e[i].next){ v = e[i].to; if(v == fa) continue; dfs(v, u); for(int j = siz[u] + siz[v]; j; j--) tp[j] = 0; // u > v if(e[i].val == 1) for(int j = 1; j <= siz[u]; j++) for(int k = 1; k <= siz[v]; k++) add(tp[j + k], C[j + k - 1][k] * C[siz[u] + siz[v] - j - k][siz[v] - k] % mod * f[u][j] % mod * sum[v][k]); else for(int j = 1; j <= siz[u]; j++) for(int k = 0; k < siz[v]; k++) add(tp[j + k], C[j + k - 1][k] * C[siz[u] + siz[v] - j - k][siz[v] - k] % mod * f[u][j] % mod * (sum[v][siz[v]] - sum[v][k] + mod)); siz[u] += siz[v]; for(int j = 1; j <= siz[u]; j++) f[u][j] = tp[j]; } sum[u][0] = 0; for(int i = 1; i <= siz[u]; i++){ sum[u][i] = sum[u][i - 1] + f[u][i]; if(sum[u][i] >= mod) sum[u][i] -= mod; } } void init(){ n = readint(); cnt = 0; for(int i = 0; i < n; i++) fir[i] = 0; int u, v; char ch; for(int i = 1; i < n; i++){ u = readint(); ch = *++ptr; while(ch != ‘<‘ && ch != ‘>‘) ch = *++ptr; v = readint(); if(ch == ‘>‘) ins(u, v, 1); else ins(u, v, 0); } for(int i = 0; i < n; i++) for(int j = 1; j <= n; j++) f[i][j] = 0; } void init_C(){ for(int i = 0; i <= 1000; i++) C[i][0] = 1; for(int i = 1; i <= 1000; i++) for(int j = 1; j <= i; j++){ C[i][j] = C[i - 1][j - 1] + C[i - 1][j]; if(C[i][j] >= mod) C[i][j] -= mod; } } int main(){ fread(buf, sizeof(char), sizeof(buf), stdin); init_C(); int T = readint(); while(T--){ init(); dfs(0, -1); printf("%lld\n", sum[0][n]); } return 0; }
标签:read comet http char ext dfs div 节点 content
原文地址:http://www.cnblogs.com/ruoruoruo/p/7627161.html