2019-10-11
prufer定理要死记硬背啊
构造
找到编号最小的度数为1的点
删除该节点并在序列中添加与该节点相连的节点的编号
重复1,2操作,直到整棵树只剩下两个节点
反推
每次取出prufer序列中最前面的元素u
在点集中找到编号最小的没有在prufer序列中出现的元素v
给u,v连边然后分别删除
最后在点集中剩下两个节点,给它们连边
然后,度数为d1~dn的方案数为
(
n
−
2
)
!
∏
i
=
1
n
(
d
i
−
1
)
!
\frac{(n-2)!}{\prod_{i=1}^{n}(d_i-1)!}
∏i=1n(di−1)!(n−2)!
然后
可以用生成函数或者别的方式得出
a
1
a
m
a_1~a_m
a1 am大小联通块联通起来的方案数
∏
i
=
1
m
a
i
n
m
−
2
\prod_{i=1}^{m}a_in^{m-2}
∏i=1mainm−2
然后采用上面那个思路可以做到
O
(
n
2
)
O(n^2)
O(n2)
单位根反演:
[
n
∣
k
]
=
1
n
∑
i
=
0
n
−
1
ω
n
i
k
[n|k]=\frac{1}{n}\sum_{i=0}^{n-1}\omega_{n}^{ik}
[n∣k]=n1∑i=0n−1ωnik
2019-10-12
最大闭合权子图的做法
若 ?? < 0 建边 ?, ? ,价格(容量)为 −??
若 ?? > 0 建边 ?,? ,价格(容量)为 ??
[有趣](https://img-blog.csdn.net/20171229193800078?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvU3RhcnJpYQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
2019-10-14
扩展欧拉定理
(
a
,
p
)
=
1
a
b
≡
a
b
m
o
d
φ
(
p
)
(a,p)=1 a^b\equiv a^{b\ mod\ \varphi(p)}
(a,p)=1ab≡ab mod φ(p)
(
a
,
p
)
!
=
1
,
b
>
=
φ
(
p
)
,
a
b
≡
b
m
o
d
φ
(
p
)
+
φ
(
p
)
,
b
<
φ
(
p
)
,
a
b
≡
a
b
(a,p)!=1,b>=\varphi(p),a^b\equiv^{b\ mod \varphi(p)+\varphi(p)},b<\varphi(p),a^b\equiv a^b
(a,p)!=1,b>=φ(p),ab≡b modφ(p)+φ(p),b<φ(p),ab≡ab
2019-10-15
老C的方块
主要是染色加转化为最小割模型
老C的键盘
容斥一下
如果说全是<,那么方案数为
n
!
∑
s
i
z
\frac{n!}{\sum siz}
∑sizn!
那么考虑一个>,方案数为所有减去<的
所以这启示我们容斥
容斥系数为
(
−
1
)
>
′
变
成
′
<
的
方
案
数
(-1)^{>'变成'<的方案数}
(−1)>′变成′<的方案数
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int Mod=1000000007;
int n;
#define Maxn 105
int inv[Maxn],fact[Maxn];
char ch[Maxn];
int head[Maxn],v[Maxn],w[Maxn],nxt[Maxn],tot=0;
inline void add_edge(int s,int e,int t){tot++;v[tot]=e;w[tot]=t;nxt[tot]=head[s];head[s]=tot;}
int dp[Maxn][Maxn],siz[Maxn],tmp[Maxn];
void dfs(int u){
siz[u]=1;dp[u][1]=1;
for(int i=head[u];i;i=nxt[i]){
dfs(v[i]);
memset(tmp,0,sizeof(int)*(siz[u]+siz[v[i]]+1));
for(int j=1;j<=siz[u];++j)
for(int k=1;k<=siz[v[i]];++k)
if(w[i])tmp[j+k]=(tmp[j+k]+1ll*dp[u][j]*dp[v[i]][k])%Mod;
else{
tmp[j]=(tmp[j]+1ll*dp[u][j]*dp[v[i]][k])%Mod;
tmp[j+k]=(tmp[j+k]-1ll*dp[u][j]*dp[v[i]][k]%Mod+Mod)%Mod;
}
siz[u]+=siz[v[i]];
memcpy(dp[u],tmp,sizeof(int)*(siz[u]+1));
}
for(register int i=1;i<=siz[u];++i)dp[u][i]=1ll*dp[u][i]*inv[i]%Mod;
}
int main(){
scanf("%d",&n);
fact[0]=1;
for(register int i=1;i<=n;++i)fact[i]=1ll*fact[i-1]*i%Mod;
inv[0]=inv[1]=1;
for(register int i=2;i<=n;++i)inv[i]=1ll*(Mod-Mod/i)*inv[Mod%i]%Mod;
scanf("%s",ch+2);
for(register int i=2;i<=n;++i)add_edge(i/2,i,ch[i]=='<');
dfs(1);
int Ans=0;
for(register int i=1;i<=n;++i)Ans=(Ans+dp[1][i])%Mod;
printf("%d\n",1ll*Ans*fact[n]%Mod);
return 0;
}