初三上学期比赛笔记part3

这篇博客记录了作者在初三上学期数学竞赛的学习笔记,主要涉及Prufer定理的构造与反推过程,最大闭合权子图问题,扩展欧拉定理的应用,以及染色和转化为最小割模型的问题。笔记中还提到了利用生成函数解决特定问题的方法,并提及了一种容斥原理的应用场景。
摘要由CSDN通过智能技术生成

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(di1)!(n2)!
然后
可以用生成函数或者别的方式得出 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=1mainm2
在这里插入图片描述
然后采用上面那个思路可以做到 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} [nk]=n1i=0n1ω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)=1abab 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),abb modφ(p)+φ(p),b<φ(p),abab

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;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值