题解:
首先不等关系是一颗树, 可以直接树上DP。
有个很妙的转化是把一个序列看做对每个数分配排名。 然后记 fi,j f i , j 表示 i i 子树有个排名的方案数, 然后问题就变为了如何合并两个排名序列。
把一个排名看做一个球,相当于有 i i 个白球个黑球,合并为 k k 个球的方案数为。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair <int,int> pii;
inline int rd() {
char ch=getchar(); int i=0,f=1;
while(!isdigit(ch)) {if(ch=='-')f=-1; ch=getchar();}
while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=getchar();}
return i*f;
}
const int N=1e2+50, mod=1e9+7;
inline int add(int x,int y) {return (x+y>=mod) ? (x+y-mod) : (x+y); }
inline int dec(int x,int y) {return (x-y<0) ? (x-y+mod) : (x-y);}
inline int mul(int x,int y) {return (LL)x*y%mod;}
inline int power(int a,int b,int rs=1) {
for(;b;b>>=1,a=mul(a,a)) if(b&1) rs=mul(rs,a);
return rs;
}
int n,m,C[N][N],anc[N],fa[N],vis[N],sze[N],f[N][N];
inline int ga(int x) {return (anc[x]==x) ? x : (anc[x]=ga(anc[x]));}
vector <pii> e;
vector <int> edge[N];
inline bool findcir(int i) {
for(int p=fa[i];p;p=fa[p]) if(p==i) return true;
return false;
}
inline void dfs(int x) {
static int tmp[N];
if(!edge[x].size()) {f[x][1]=1; sze[x]=1; return;}
for(int i=edge[x].size()-1;i>=0;i--) {
int v=edge[x][i]; dfs(v);
if(v==edge[x].back()) {
for(int j=1;j<=sze[v];++j) f[x][j]=f[v][j];
} else {
memset(tmp,0,sizeof(tmp));
for(int j=1;j<=sze[v];++j)
for(int k=1;k<=sze[x];++k)
for(int z=max(k,j);z<=k+j;z++)
tmp[z]=add(tmp[z],mul(mul(f[v][j],f[x][k]),mul(C[z][j],C[j][k-(z-j)])));
for(int j=1;j<=sze[x]+sze[v];++j) f[x][j]=tmp[j];
}
sze[x]+=sze[v];
}
++sze[x];
for(int i=sze[x];i;i--) f[x][i]=f[x][i-1];
}
int main() {
n=rd(), m=rd();
for(int i=0;i<=n;i++)
C[i][0]=1, anc[i]=i;
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
C[i][j]=add(C[i-1][j-1],C[i-1][j]);
for(int i=1;i<=m;i++) {
static char ch[5];
static int x,y;
scanf("%d%s%d",&x,ch+1,&y);
if(ch[1]=='<') e.push_back(pii(x,y));
else anc[ga(x)]=ga(y);
}
for(int i=0;i<e.size();++i) {
pii &u=e[i];
fa[ga(u.second)]=ga(u.first);
}
for(int i=1;i<=n;i++)
if(ga(i)==i && findcir(i))
return puts("0"),0;
for(int i=1;i<=n;i++)
if(ga(i)==i) edge[fa[i]].push_back(i);
dfs(0); int ans=0;
for(int i=1;i<=sze[0];++i) ans=add(ans,f[0][i]);
cout<<ans;
}