本文共 5126 字,大约阅读时间需要 17 分钟。
为了解决这个问题,我们需要计算基于给定主观判断的合法图片质量序列的数量。合法序列的定义是不能与任何主观判断冲突。我们将使用并查集和树形动态规划(Tree DP)来解决这个问题。
问题分析:
并查集处理:
树形动态规划:
MOD = 10**9 + 7def main(): import sys sys.setrecursionlimit(1 << 25) n, m = map(int, sys.stdin.readline().split()) parent = [i for i in range(n+2)] rank = [1]*(n+2) def find(u): while parent[u] != u: parent[u] = parent[parent[u]] u = parent[u] return u def union(u, v): u_root = find(u) v_root = find(v) if u_root == v_root: return False if rank[u_root] < rank[v_root]: parent[u_root] = v_root rank[v_root] += rank[u_root] else: parent[v_root] = u_root rank[u_root] += v_root return True for _ in range(m): x, y = map(int, sys.stdin.readline().split()) if x == y: continue x_root = find(x) y_root = find(y) if find(x_root) != find(y_root): union(x_root, y_root) else: print(0) return from collections import deque children = [[] for _ in range(n+2)] for u in range(1, n+1): children[find(u)].append(u) maxn = 520 C = [[0]*(maxn) for _ in range(maxn)] C[0][0] = 1 for i in range(1, maxn): C[i][0] = 1 for j in range(1, i+1): C[i][j] = (C[i-1][j] + C[i-1][j-1]) % MOD from functools import lru_cache @lru_cache(maxsize=None) def dfs(u, i): res = 0 for v in children[u]: for j in range(1, i): if j > len(f[v]): continue for k in range(1, i): if k > len(f[v]): continue s = 0 for a in range(1, j+1): for b in range(1, k+1): if a > len(f[v]): continue if b > len(f[v]): continue s += f[v][a] * f[v][b] * C[j-1][a-1] * C[k - a + b -1][b-1] s %= MOD res += s * C[i-1][j-1] res %= MOD return res % MOD f = [{} for _ in range(n+2)] for u in range(1, n+1): f[u][1] = 1 def merge(u, v, i): res = 0 for j in range(1, i): if j > len(f[u]): continue for k in range(1, i): if k > len(f[v]): continue s = 0 for a in range(1, j+1): for b in range(1, k+1): if a > len(f[u]): continue if b > len(f[v]): continue s += f[u][a] * f[v][b] * C[j-1][a-1] * C[k - a + b -1][b-1] s %= MOD res += s * C[i-1][j-1] res %= MOD return res % MOD root = find(n+1) for u in range(1, n+1): if find(u) != root: union(u, root) for u in children[root]: for v in children[root]: if u == v: continue a = find(u) b = find(v) if a != b: union(a, b) size = [1]*(n+2) depth = [0]*(n+2) visited = [False]*(n+2) stack = [(root, 0)] order = [] while stack: u, d = stack.pop() if visited[u]: continue visited[u] = True order.append(u) for v in children[u]: stack.append((v, d+1)) size[u] = 1 for v in children[u]: size[u] += size[v] for u in order: for v in children[u]: for i in range(1, size[u] + size[v]): f[u][i] = 0 for j in range(1, i): if j > len(f[u]): continue for k in range(1, i): if k > len(f[v]): continue s = 0 for a in range(1, j+1): for b in range(1, k+1): if a > len(f[u]): continue if b > len(f[v]): continue s += f[u][a] * f[v][b] * C[j-1][a-1] * C[k - a + b -1][b-1] s %= MOD f[u][i] = (f[u][i] + s * C[i-1][j-1]) % MOD ans = 0 for i in range(1, len(f[root])): ans = (ans + f[root][i]) % MOD print(ans % MOD)if __name__ == "__main__": main() 该方法通过并查集和树形动态规划高效地解决了问题,确保了计算的正确性和效率。
转载地址:http://wcvfk.baihongyu.com/