\(Description\)

有\(n\)个元素,对于每个元素\(x_i\)最多知道一个形如\(x_j < x_i\)或\(x_j=x_i\)的条件,问有多少合法的序列.合法的序列满足每个元素出现一次,任一相邻两元素之间有小于号或或等于号,并且所有条件全部满足,但是对于两个序列,如果只修改相等元素的位置能使得他们一样,则是他们为同一序列,答案队\(10^9\)取模

\(n<=100\)

\(Solution\)

认真读题后可以发现:

对于每个元素\(x_i\)最多知道一个形如\(x_j<x_i\)或\(x_j=x_i\)的条件

若\(x_j=x_i\)

将\((i,j)\)合并,

若\(x_j<x_i\),

将\(j\)连向\(i\)

最后建立一个超级根节点,将这个点连向所有入读为\(0\)的点

这样就是一棵树了.

用\(f[i][j]\)表示以\(i\)为根的子树中的元素能分\(j\)段,使\(j\)段每段相等的合法序列数

首先给出转移方程:

\[f[x][i]=f'[x][j]*f[v][k]*C_{i-1}^{j-1}*C_{j-1}^{k-i+j}
\]

\(f'[x]\)表示在\(v\)之前的\(f\)值

v为x的子树

\[C_{i-1}^{j-1}*C_{j-1}^{k-i+j}
\]

上面式子表示将\(j\)段和\(k\)段合并为\(i\)段的方案数.

至于为什么?

就是\(j-1\)放在\(x\)的方案数\(*v\)剩下的段余B合并的方案数:

\(Code\)

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
const int mod=1e9+7;
int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar();
while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x*f;
}
int c[1011][1011],f[1001][1001],siz[10011],dp[10010],head[10010],cnt;
struct node {
int to,next;
}a[10011];
void add(int x,int y){
a[++cnt].to=y,a[cnt].next=head[x],head[x]=cnt;
a[++cnt].to=x,a[cnt].next=head[y],head[y]=cnt;
}
void init(){
for(int i=0;i<=200;i++)
c[i][i]=c[i][0]=1;
for(int i=2;i<=200;i++)
for(int j=1;j<i;j++)
c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
}
void dfs(int x,int fa){
siz[x]=f[x][1]=1;
for(int e=head[x];e;e=a[e].next){
int v=a[e].to;
if(v==fa)
continue;
dfs(v,x);
memset(dp,0,sizeof(dp));
for(int i=1;i<=siz[x]+siz[v];i++)
for(int j=1;j<=siz[x];j++)
for(int k=1;k<=siz[v];k++){
int z=k-i+j;
if(z<0) continue;
(dp[i]+=f[x][j]*f[v][k]%mod*c[i-1][j-1]%mod*c[j-1][z]%mod)%=mod;
}
siz[x]+=siz[v];
for(int i=1;i<=siz[x];i++)
f[x][i]=dp[i];
}
}
int X[100001],Y[10001],pre[10001],flag[10010],bj[10010],vis[10010],fa[10010];
int find(int x){
return (x==pre[x])?x:pre[x]=find(pre[x]);
}
int find1(int x){
return (x==fa[x])?x:fa[x]=find1(fa[x]);
}
void join(int x,int y){
int fx=find(x),fy=find(y);
if(fx!=fy)
pre[fx]=fy,fa[fx]=fy;
}
main(){
init();
int n=read(),m=read(),x,y;
char s;
for(int i=1;i<=n;i++)
pre[i]=i,fa[i]=i;
for(int i=1;i<=m;i++){
X[i]=read(),scanf("%c",&s),Y[i]=read();
if(s=='=')
flag[i]=1,join(X[i],Y[i]);
}
for(int i=1;i<=m;i++)
if(!flag[i]){
int fx=find(X[i]),fy=find(Y[i]);
add(fx,fy),vis[fy]++;
if(find1(X[i])==find1(Y[i]))
puts("0"),exit(0);
fa[find1(X[i])]=find1(Y[i]);
}
for(int i=1;i<=n;i++)
bj[find(i)]=1;
for(int i=1;i<=n;i++)
if(bj[i]&&!vis[i])
add(n+1,i);
dfs(n+1,0);
int ans=0;
for(int i=1;i<=siz[n+1];i++)
ans+=f[n+1][i],ans%=mod;
printf("%lld ",ans);
}

「HNOI 2015」实验比较的更多相关文章

  1. 「HNOI 2015」亚瑟王

    \(Description\) 有\(n\)张卡牌,每一张卡牌有\(p_i\)的概率发动,并造成\(d_i\)点伤害.一共有\(r\)轮,每一轮按照编号从小到大依次考虑,如果这张牌已经发动过则跳过该牌 ...

  2. 「HNOI 2015」菜肴制作

    题目链接 戳我 \(Description\) 有若干限制,需要求一个\(1\)到\(n\)的排列,每个限制\((x,y)\)表示\(x\)必须在\(j\)之前,并要求所求的排列满足所有限制并让\(1 ...

  3. 「HNOI 2015」落忆枫音

    题目链接 戳我 \(Description\) 给一张\(n\)割点\(m\)条边的\(DAG\),保证点\(1\)不存在入边,现在需要在\(DAG\)中加入一条不在原图中的边\((x,y)\),求这 ...

  4. LOJ#3054. 「HNOI 2019」鱼

    LOJ#3054. 「HNOI 2019」鱼 https://loj.ac/problem/3054 题意 平面上有n个点,问能组成几个六个点的鱼.(n<=1000) 分析 鱼题,劲啊. 容易想 ...

  5. GDOI#345. 送礼物「JSOI 2015」01分数规划+RMQ

    题目描述 JYY和CX的结婚纪念日即将到来,JYY来到萌萌开的礼品店选购纪念礼物.萌萌的礼品店很神奇,所有出售的礼物都按照特定的顺序都排成一列,而且相邻的礼物之间有一种神秘的美感.于是,JYY决定从中 ...

  6. 「HNOI 2019」白兔之舞

    一道清真的数论题 LOJ #3058 Luogu P5293 题解 考虑$ n=1$的时候怎么做 设$ s$为转移的方案数 设答案多项式为$\sum\limits_{i=0}^L (sx)^i\bin ...

  7. 「HNOI 2016」 序列

    \(Description\) 给你一个序列,每次询问一个区间,求其所有子区间的最小值之和 \(Solution\) 这里要用莫队算法 首先令\(val\)数组为原序列 我们考虑怎么由一个区间\([l ...

  8. 「HNOI 2014」 江南乐

    \(Description\) \(n\)堆石子,每堆石子有\(s_i\)个,两个人轮流操作,每次可以将一对不少于\(F\)的石子尽量平均分成\(m\)堆,\(m\)每次自选,不能操作者输.共有\(T ...

  9. 「HNOI 2014」 画框

    题目链接 戳我 \(Solution\) 这一题很像最小乘积生成树.只是把\(kruskal\)变为了\(km\)/费用流 现在来讲一讲最小乘积生成树.首先将\(\sum a_i\)和\(\sum b ...

随机推荐

  1. 高斯白噪声(white Gaussian noise,WGN)

    本文科普一下高斯白噪声(white Gaussian noise,WGN). 百度百科上解释为“高斯白噪声,幅度分布服从高斯分布,功率谱密度服从均匀分布”,听起来有些晦涩难懂,下面结合例子通俗而详细地 ...

  2. 在ubuntu14.04上搭建OpenVPN服务

    简介 在连接了不可信的网络环境后,让手机或者计算机安全的访问互联网,使用虚拟专用网络(Virtual Private Network,VPN)是一个解决办法.OpenVPN是一个SSL VPN完整解决 ...

  3. springmvc怎么在启动时自己执行一个线程

    之前使用springmvc的时候,都是写好controller和对应的数据库操作. 外界发请求的时候,controller进行一堆操作后返回相应的json数据. 似乎springmvc就是外界驱动的一 ...

  4. selenium webdriver——JS操作日历控件

    一般的日期控件都是input标签下弹出来的,如果使用webdriver 去设置日期, 1. 定位到该input 2. 使用sendKeys 方法 比如 但是,有的日期控件是readonly的 比如12 ...

  5. [jOOQ中文]2. jOOQ与Spring和Druid整合

    https://segmentfault.com/a/1190000010496053 jOOQ和Spring很容易整合. 在这个例子中,我们将整合: Alibaba Druid(但您也可以使用其他连 ...

  6. UNITY 接讯飞语音过程总结

    11:13 2017/3/141,安装问题:JDK与ECLIPSE位数一定要对应,32位对64位会出现 java was returned ....code 13的弹框错误.版本号可以不一致.2,EC ...

  7. python之with...as

    [python之with...as] 参考:http://python.42qu.com/11155501

  8. Excel VBA入门(八)单元格边框

    本文基于以下文件 http://pan.baidu.com/s/1nvJtsu9 (部分)内容预览: 1. 边框样式 Sub cell_format() Dim sht As Worksheet Di ...

  9. java基础二(阅读Head First Java记录)

    写在前面的话 本部分是在语法基础上的一些内容,比如内部java函数库,继承多态等   “与”和“或”运算符 1.短运算符(&&,||)    &&与,必须表达式两边都为 ...

  10. redis客户端执行命令没反应

    问题:redis-cli连接客户端后,执行命令没有反应   解决方法:通过指定一个开启守护进程的配置文件来启动服务,redis-server ../redis.conf 说明:redis.conf是我 ...