Description

小D被邀请到实验室,做一个跟图片质量评价相关的主观实验。实验用到的图片集一共有\(N\)张图片,编号为\(1\)到\(N\)。实验分若干轮进行,在每轮实验中,小\(D\)会被要求观看某两张随机选取的图片,然后小\(D\)需要根据他自己主观上的判断确定这两张图片谁好谁坏,或者这两张图片质量差不多。用符号“\(<\)”、“\(>\)”和“\(=\)”表示图片\(x\)和\(y\)(\(x,y\)为图片编号)之间的比较:如果上下文中\(x\)和\(y\)是图片编号,则\(x < y\)表示图片\(x\)“质量优于”\(y\),\(x > y\)表示图片\(x\)“质量差于”\(y\),\(x = y\)表示图片\(x\)和\(y\)“质量相同”;也就是说,这种上下文中,“\(<\)”、“\(>\)”、“\(=\)”分别是质量优于、质量差于、质量相同的意思;在其他上下文中,这三个符号分别是小于、大于、等于的含义。图片质量比较的推理规则(在\(x\)和\(y\)是图片编号的上下文中):(1)\(x < y\)等价于\(y > x\)。(2)若\(x < y\)且\(y = z\),则\(x < z\)。(3)若\(x < y\)且\(x = z\),则\(z < y\)。(4)\(x=y\)等价于\(y=x\)。(5)若\(x=y\)且\(y=z\),则\(x=z\)。 实验中,小 D 需要对一些图片对\((x,y)\),给出\(x < y\) 或\(x = y\)或\(x > y\)的主观判断。小\(D\)在做完实验后, 忽然对这个基于局部比较的实验的一些全局性质产生了兴趣。在主观实验数据给定的情形下,定义这\(N\)张图片的一个合法质量序列为形如“\(x_{1}\;R_{1}\;x_{2}\;R_{2}\;x_{3}\;R_{3} \cdots x_{N-1}\;R_{N-1}\;x_{N}\)”的串,也可看作是集合\(\lbrace x_{i}\;R_{i}\;x_{i+1} \mid 1 \le i \le N-1 \rbrace\),其中\(x_{i}\)为图片编号,\(x_{1},x_{2},\cdots,x_{N}\)两两互不相同(即不存在重复编号),\(R_{i}\)为<或=,“合法”是指这个图片质量序列与任何一对主观实验给出的判断不冲突。 由于实验已经做完一段时间了,小D已经忘了一部分主观实验的数据。对每张图片\(i\),小 D 都{最多只记住了某一张质量不比\(i\)差的另一张图片\(K_{i}\)。这些小\(D\)仍然记得的质量判断一共有\(M\)条\((0 \le M \le N)\),其中第\(i\)条涉及的图片对为\((K_{X_{i}}, X_{i})\),判断要么是\(K_{X_{i}} < X_{i}\),要么是\(K_{X_{i}}=X_{i}\),而且所有的\(X_{i}\)互不相同。小D打算就以这\(M\)条自己还记得的质量判断作为他的所有主观数据。现在,基于这些主观数据,我们希望你帮小D求出这 \(N\)张图片一共有多少个不同的合法质量序列。我们规定:如果质量序列中出现“\(x=y\)”,那么序列中交换\(x\)和\(y\)的位置后仍是同一个序列。因此: \(1<2=3=4<5\)和\(1<4=2=3<5\)是同一个序列,\(1 < 2 = 3\)和\(1 < 3 = 2\)是同一个序列,而\(1 < 2 < 3\)与\(1 < 2 = 3\)是不同的序列,\(1<2<3\)和\(2<1<3\)是不同的序列。由于合法的图片质量序列可能很多, 所以你需要输出答案对\(10^{9}+7\)取模的结果。

Input

第一行两个正整数\(N,M\),分别代表图片总数和小D仍然记得的判断的条数;

接下来\(M\)行,每行一条判断,每条判断形如“\(x < y\)”或者”\(x = y\)”。

Output

输出仅一行,包含一个正整数,表示合法质量序列的数目对\(10^{9}+7\)取模的结果。

Sample Input

5 4

1 < 2

1 < 3

2 < 4

1 = 5

Sample Output

5

Hint

\(N \le 100\)

将\(=\)缩掉之后如果该图没有环,那么一定是一棵森林结构,我们增添超级根,就变成了一颗树的结构了。

如果\(A,B\)可以用\(=\)关系的话,那么\(A,B\)一定没有子树关系。所以,我们可以想到状态\(f_{i,j}\)表示以\(i\)为根的子树,有\(j\)段(\(j-1\)个\(<\)的方案数)。利用辅助数组进行转移\(g_{i,j,k}\)表示\(i\)的前\(j\)个儿子,分成了\(k\)段的方案数。那么我们就有转移$$g_{i,j,z} = \sum C_{z}^{x} C_{x}^{x+y-z} g_{i,j-1,x} \times f_{son,y}(max(x,y) \le z \le x+y)$$

其中\(C_{z}^{x} C_{x}^{x+y-z}\)是转移系数,表示有\(x\)个白球,\(y\)个黑球,放进\(z\)个槽中,每个位置不能有两个颜色一样的球的方案数。

#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<queue>
using namespace std; typedef long long ll;
#define rhl (1000000007)
#define maxn (110)
int father[maxn],side[maxn],next[maxn],toit[maxn],g[2][maxn][maxn];
int tot,num,cnt,ind[maxn],C[maxn][maxn],f[maxn][maxn],ans,N,M;
bool exist[maxn];
struct node { int a,b; }edge[maxn]; inline int find(int a) { if (father[a] != a) father[a] = find(father[a]); return father[a]; }
inline void add(int a,int b)
{
next[++cnt] = side[a]; side[a] = cnt;
toit[cnt] = b; ++ind[b]; exist[a] = exist[b] = true;
} inline bool topsort()
{
queue <int> team;
for (int i = 1;i <= N;++i) if (exist[i]&&!ind[i]) team.push(i),add(0,i);
int ret = 0;
while (!team.empty())
{
++ret; int now = team.front(); team.pop();
for (int i = side[now];i;i = next[i])
if (!--ind[toit[i]]) team.push(toit[i]);
}
return ret == num;
} inline int dp(int now)
{
int sz = 0,tmp,cur = 1;
g[0][now][0] = 1;
for (int i = side[now],v;i;i = next[i],cur ^= 1)
{
tmp = dp(v = toit[i]);
for (int x = 0;x <= sz;++x)
for (int y = 1;y <= tmp;++y)
for (int z = max(x,y);z <= x+y;++z)
{
g[cur][now][z] += (ll)g[cur^1][now][x]*f[v][y]%rhl*(ll)C[z][x]%rhl*(ll)C[x][x+y-z]%rhl;
if (g[cur][now][z] >= rhl) g[cur][now][z] -= rhl;
}
memset(g[cur^1][now],0,sizeof(g[cur^1][now]));
sz += tmp;
}
for (int i = 0;i <= sz;++i) f[now][i+1] = g[cur^1][now][i];
return sz+1;
} int main()
{
freopen("4013.in","r",stdin);
freopen("4013.out","w",stdout);
scanf("%d %d",&N,&M); num = N;
for (int i = 1;i <= N;++i) father[i] = i;
for (int i = 1,a,b;i <= M;++i)
{
char c;
scanf("%d %c %d\n",&a,&c,&b);
if (c == '<') edge[++tot] = (node){a,b};
else
{
int r1 = find(a),r2 = find(b);
if (r1 != r2) father[r1] = r2,--num;
}
}
for (int i = 1;i <= tot;++i) add(find(edge[i].a),find(edge[i].b));
if (!topsort()) printf("0");
else
{
C[0][0] = 1;
for (int i = 1;i <= N;++i)
{
C[i][0] = 1;
for (int j = 1;j <= i;++j)
{
C[i][j] = C[i-1][j] + C[i-1][j-1];
if (C[i][j] >= rhl) C[i][j] -= rhl;
}
}
int sz = dp(0);
for (int i = 1;i <= sz;++i) { ans += f[0][i]; if (ans >= rhl) ans -= rhl; }
printf("%d",ans);
}
fclose(stdin); fclose(stdout);
return 0;
}

BZOJ 4013 实验比较的更多相关文章

  1. bzoj 4013: [HNOI2015]实验比较

    Description 小D 被邀请到实验室,做一个跟图片质量评价相关的主观实验.实验用到的图片集一共有 N 张图片,编号为 1 到 N.实验分若干轮进行,在每轮实验中,小 D会被要求观看某两张随机选 ...

  2. BZOJ 4013 【HNOI2015】 实验比较

    题目链接:实验比较 如果我们把相等关系全部缩起来的话,这道题给出的小于关系如果有环,那么就是不合法的,否则就构成了一片森林. 定义等于号连起来的所有变量看做一个块. 然后我们就可以令\(f_{i,j} ...

  3. BZOJ 4013/Luogu P3240 [HNOI2015] 实验比较 (树形DP)

    题目传送门 分析 放一个dalao博客: xyz32768 的博客,看完再回来看本蒟蒻的口胡吧(其实嘛-不回来也行) 精髓是合并的方案数的计算,至于为什么是Ci−1j−1\large C_{i-1}^ ...

  4. 【BZOJ】4013: [HNOI2015]实验比较

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4013 中第i 条涉及的图片对为(KXi, Xi),判断要么是KXi < Xi ,要么 ...

  5. 4013: [HNOI2015]实验比较

    4013: [HNOI2015]实验比较 链接 分析: 首先把等号用并查集合并起来. 由于只存在最多一个质量不比i差的数,发现这是森林.若x<y,连边x->y.于是建虚拟根节点0. 然后树 ...

  6. 【BZOJ】【3280】小R的烦恼

    网络流/费用流 和软件开发那题基本相同,只是多加了一个“雇佣研究生”的限制:不同价格的研究生有不同的数量…… 那么只需加一个附加源点,对每一种研究生连边 S->ss 容量为l[i],费用为p[i ...

  7. BZOJ 3786 星系探索

    Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球 ...

  8. bzoj 4824: [Cqoi2017]老C的键盘

    Description 老 C 是个程序员.     作为一个优秀的程序员,老 C 拥有一个别具一格的键盘,据说这样可以大幅提升写程序的速度,还能让写出来的程序 在某种神奇力量的驱使之下跑得非常快.小 ...

  9. 【BZOJ4013】[HNOI2015]实验比较(动态规划)

    [BZOJ4013][HNOI2015]实验比较(动态规划) 题面 BZOJ 洛谷 题解 看题目意思就是给你一棵树,连边表示强制顺序关系.然后你要给点染色,在满足顺序关系的情况下,将序列染成若干个颜色 ...

随机推荐

  1. [TypeScript] Using Exclude and RootDir until File Globs Lands in 2.0.

    Files globs will be available in TypeScript 2.0, so in the meantime, we need to use "exclude&qu ...

  2. [Javascript] IIFE

    Javascript modules are a design pattern that allow you to encapsulate your code into smaller self ma ...

  3. 传输层:TCP UDP SCTP

    总图 虽然协议族被称为“TCP/IP”,但除了TCP和IP这两个主要协议外,还有许多其他成员.图2-1展示了这些协议的概况. 图2-1中同时展示了IPV4和IPV6.从右向左看该图,最右边的5个网络应 ...

  4. Paxos算法之旅(四)zookeeper代码解析--转载

    ZooKeeper是近期比较热门的一个类Paxos实现.也是一个逐渐得到广泛应用的开源的分布式锁服务实现.被认为是Chubby的开源版,虽然具体实现有很多差异.ZooKeeper概要的介绍可以看官方文 ...

  5. 构建可克隆的对象(ICloneable)

    ICloneable接口 如果想使自己的自定义类型支持向调用方返回自身同样副本的能力,需要实现标准ICloneable接口. namespace System { // // 摘要: // Suppo ...

  6. jQuery获取radio选中项的值【转藏】

    <title></title> <script src="js/jquery-1.7.2.min.js"></script> < ...

  7. .Net开源SqlServer ORM框架SqlSugar整理

    一.链接整理 官方Git源代码地址: https://github.com/sunkaixuan/SqlSugar 最新发布版更新地址:当前版本Release 3.5.2.1 https://gith ...

  8. Entity Framework性能优化

    AsNonUnicode 执行如下语句,并用SqlProfiler监控其SQL: var list = WMFactory.ReChargeMobile.Queryable().Where(w =&g ...

  9. mysql - 查看Port

    show global variables like 'port';

  10. 淘宝链接中的spm参数

    什么是SPM SPM是淘宝社区电商业务(xTao)为外部合作伙伴(外站)提供的一套跟踪引导成交效果数据的解决方案. 下面是一个跟踪点击到宝贝详情页的引导成交效果数据的SPM示例: http://det ...