5.22考试总结(NOIP模拟1)

5.22考试总结(NOIP模拟1)

改题记录

T1 序列

题解

暴力思路很好想,分数也很好想\(QAQ\) (反正我只拿了5pts)

正解的话:

先用欧拉筛把1~n的素数筛出来

void get_Prime()
{
	for(int i=2;i<=M;i++)
	{
		if(!b[i])
			pri[++tot]=i;
		for(int j=1;j<=tot&&i*pri[j]<=M;j++)
		{
			b[i*pri[j]]=true;
			if(!(i%pri[j]))
				break;
		}
	}
}

然后对于p=1的情况进行特殊处理,也就是求一下序列中连续的一样的数

for(int i=1;i<=n;i++)
{
	if(s[i]==s[i-1])
		res++;
	else
	{
		ans=max(ans,res);
		res=1;
	}
	ans=max(ans,res);
}

主要就是对于p>1的处理了。。。

对于是s[i]和是s[i-1]求一下他们最小的公比

假设其中比较大的一个为 x,另一个 y。

  1. 首先要满足 x%y=0

  2. 让 z=x/y,然后把 z 质因数分解,z=\(p_1^{q_1}*p_2^{q_2}*p_3^{q_3}......\),

\(Gcd=gcd(q_1,q_2,q_3...)\),那么当前序列的最小公比就是 \(p_1^{q_1/Gcd}*p_2^{q_2/Gcd}*......\)

将数据存到一个pl数组里,
pl[i]表示s[i]与s[i-1]d最小公比


int find(int x,int y)
{
	if(y>x)
		swap(x,y);
	if(x%y)
		return 0;
	int temp=x/y,cnt=0,ret=1,Gcd;
	memset(p,0,sizeof(p));
	memset(q,0,sizeof(q));
	for(int i=1;i<=tot;i++)
	{
		if(temp==1)
			break;
		if(temp%pri[i])
			continue;
		p[++cnt]=pri[i];
		while(temp!=1&&temp%pri[i]==0)
		{
			temp/=pri[i];
			q[cnt]++;
		}
	}
	Gcd=q[1];
	for(int i=2;i<=cnt;i++)
	{
		if(Gcd==1)
			break;
		Gcd=gcd(q[i],Gcd);
	}
	for(int i=1;i<=cnt;i++)
		ret*=ksm(p[i],q[i]/Gcd);
	return ret;
}
for(int i=2;i<=n;i++)
	pl[i]=find(s[i],s[i-1]);

接下来就是对于pl的运用了

设l表示有等比序列的一段的左端点,r为右端点

用vis数组存一下现在的序列里s[i]的位置,即vis[s[i]]=i;

遇到不可以进等比序列的直接清空vis重置l和r就OK了

\(code\)

\(T2\)熟练剖分

题解

初始化,线性求逆元什么的就不多说了,主要说一下算法主体

所谓精彩操作无非就是一个最长链
而这个东西显然是可以由子节点转移到父亲节点的。

考虑dfs,
用f[i][j]表示以1~i分别为根节点,最长链为j的概率的前缀和

对于一个点,先枚举它选择的重儿子,然后扫一遍它的所有儿子,再枚举深度

\(G[i][j]=\sum_{k=0}^{k\le j}{F[i][k]}\),

假如当前扫的儿子是 x(x 是重儿子)。

\(F[i][j]=F[x][j]*G[i][j]+G[x][j]*F[i][j]-F[x][j]*F[i][j]\)

式子的第一部分也就是\(F[x][j]*G[i][j]\)表示最长链在以x为根的子树的概率

\(G[x][j]*F[i][j]\)则表示最长链在除x及其子树外其他点的概率

两部分有一个重叠的\(F[x][j]*F[i][j]\),减去就好了

不难发现g可以在dfs中压缩到一维,

因为我们要用子节点来更新父亲节点,因此先进行对子节点的扫描,同时更新siz[i] (以i为根节点的子树的大小)

在下面对于f,g数组更新时,不难发现,siz[i]以后的是没有用的,因此只需要枚举0~siz[i]就够了

因为这一层如果同时更新g和f的话十分容易出错,因此拿一个h数组暂存一下f

剩下的就是在各种前缀和间反复横跳了。。。

\(code\)

\(T3\)建造游乐园

题解

这题是玄学的数论

首先考虑如何枚举偶数点度的图

可以考虑取出i-1个点 那么成图的数量为2^C(i-1,2)

(原因单独取出的i点能平衡已建图中的奇数点,原因是某种性质。。。。)

然后求带联通标号的欧拉图

转载自\(blog\)

\(code\)

posted @ 2021-05-22 19:16  Varuxn  阅读(79)  评论(0编辑  收藏  举报