5.5刷题(P1297,P6154,P2441)

P1297

Description

i i 题有 a i a_i 个选项。 C h e r r t Cherrt 做对了每一题,但是在最终填答题卡的时候填挫了,即第 i i 题的答案填到了第 i + 1 i+1 题上。特别的,第 n n 题的答案填到了第 1 1 题上 (我也是醉了)

求可怜的 C h e r r t Cherrt 的正确题数的期望。

Solution

容易得到,做对题数的期望就是每题做对的概率之和。

做对一题当且仅当本题的答案与上一题的答案相同。因此,第 i i 题正确的概率为 m i n ( a i , a i 1 ) a i × a i 1 \frac {min(a_i,a_{i-1})} {a_i×a_{i-1}} 。分母为选项的组合的数量,分子为第 i i 空正确的答案组合的数量。

a 0 = a n a_0=a_n ,那么所以答案就是 i = 1 n m i n ( a i , a i 1 ) a i × a i 1 ∏_{i=1}^n \frac {min(a_i,a_{i-1})} {a_i×a_{i-1}}

提前构造出数组 a a 即可。时间复杂度为 O ( n ) O(n)

Code

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n,A,B,C;
double ans=0.00;
int a[10000005];

signed main()
{
	cin>>n>>A>>B>>C>>a[1];
	for (int i=2;i<=n;i++)  a[i]=(a[i-1]*A+B)%100000001;
	for (int i=1;i<=n;i++)  a[i]=a[i]%C+1;//3 2 4
	a[0]=a[n];
	for (int i=1;i<=n;i++)
	{
		double first=min(a[i],a[i-1])*1.00,second=a[i]*a[i-1];
		ans+=first/second;
	}
	cout<<fixed<<setprecision(3)<<ans<<endl;
	
	return 0;
}

P6154

Description

给定一个 n n 个点, m m 有向边无环图,求出路径长度的期望。

Solution

本题有套路式做法,即求出所有路径的长度之和与路径的条数。为了求这两个量,我们使用 d p dp ,即状态设计 t o t l i totl_i 表示目前发现到 i i 点的所有路径的长度之和, c n t l i cntl_i 表示目前发现到 i i 点的路径的数量。

在大部分的图形dp或树形dp中,任何一个节点的 d p dp 值均转移自源于与它相邻的节点。假设我们现在想要得到 t o t l n o w totl_{now} c n t l n o w cntl_{now} 的值,那么它们必须由 y y 推到而来( y y n o w now 有一条无向边,其中 y y 连向 n o w now )。所以得到状态转移:

c n t l n o w = ( c n t l n o w + c n t y ) cntl_{now}=(cntl_{now}+cnt_y)
t o t l n o w = ( t o t l n o w + t o t l y + c n t l y ) totl_{now}=(totl_{now}+totl_y+cntl_y)

①表示, c n t l n o w cntl_{now} 的值要加上被它连接的那个点( y y )的 c n t l cntl 值,因为 c n t l y cntl_y 计算的那些路径均可以通过加一条边 y x y→x 连到 x x ,所以有 + c n t y +cnt_y 这一步。

②表示, t o t l n o w totl_{now} 的值要加上一些东西。甚么东西?即, t o t l n o w totl_{now} 计算的路径均可以通过加一条边 y x y→x 连到 x x ,这样每条路径的长度都变长了1;因此不仅要加上 t o t l y totl_y ,还要加上 c n t l y cntl_y

题解中的几位大佬都叫它记忆化搜索…… 可怜的dp啊~

Code

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod=998244353;

int n,m,cnt=0,sumv=0,num=0;
int head[1000005],totl[1000005],cntl[1000005];

struct edge
{
	int next;
	int to;
}e[2000005];

inline void add_edge(int u,int v)
{
	cnt++;
	e[cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}

inline void dfs(int now)
{
	if (cntl[now]!=0)  return;
	cntl[now]=1;
	for (int i=head[now];i;i=e[i].next)
	{
		dfs(e[i].to);
		cntl[now]=(cntl[now]+cntl[e[i].to])%mod;
		totl[now]=(totl[now]+totl[e[i].to]+cntl[e[i].to])%mod;
	}
}

int quick_power(int a,int b)
{
	if (b==0)  return 1;
	
	int res=1;
	for (;b;b=b>>1,a=(a*a)%mod)
	{
		if (b&1)  res=(res*a)%mod;
	}
	return res;
}

inline int divide(int a,int b)
{
	return (a*quick_power(b,mod-2))%mod;
}

signed main()
{
	cin>>n>>m;
	for (int i=1;i<=m;i++)
	{
		int u,v;
		cin>>u>>v;
		add_edge(u,v);
	}
	for (int i=1;i<=n;i++)
	{
		if (cntl[i]==0)  dfs(i);
	}
	for (int i=1;i<=n;i++)  sumv=(sumv+totl[i])%mod;
	for (int i=1;i<=n;i++)  num=(num+cntl[i])%mod;
	cout<<divide(sumv,num)<<endl;
	
	return 0;
}

P2441

Description

给定一棵树,支持修改某个点的点权与询问最近的与该点有公共质因子的祖先。

Solution

今天做的第 1 1 题,用来练手的~ 暴力即可

Code

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n,q,root,cnt=0;
int visited[200005],head[200005],a[200005],father[200005];

struct edge
{
	int next;
	int to;
}e[2000005];

inline void add_edge(int u,int v)
{
	cnt++;
	e[cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}

inline void dfs(int now,int fath)
{
	father[now]=fath;
	for (int i=head[now];i;i=e[i].next)
	{
		if (e[i].to!=fath)  dfs(e[i].to,now);
	}
}

inline int dfs2(int last,int now,int w)
{
	if (now==0)  return -1;
	
	if (__gcd(a[now],w)!=1&&last!=now)  return now;
	else return dfs2(last,father[now],w);
}

signed main()
{
	cin>>n>>q;
	for (int i=1;i<=n;i++)  cin>>a[i];
	for (int i=1;i<n;i++)
	{
		int u,v;
		cin>>u>>v;
		add_edge(u,v);
		add_edge(v,u);
		visited[v]=1;
	}
	for (int i=1;i<=n;i++)
	{
		if (visited[i]==0)
		{
			root=i;
			break;
		}
	}
	dfs(root,0);
	
	for (int i=1;i<=q;i++)
	{
		int flag;
		cin>>flag;
		
		if (flag==1)
		{
			int rt;
			cin>>rt;
			cout<<dfs2(rt,rt,a[rt])<<endl;
		}
		else if (flag==2)
		{
			int rt,num;
			cin>>rt>>num;
			a[rt]=num;
		}
	}
	return 0;
}

由于时间限制,本蒟蒻就说三道题啦~~~

https://www.luogu.com.cn/user/87064(PS: 这是我)

原创文章 19 获赞 27 访问量 1939

猜你喜欢

转载自blog.csdn.net/Cherrt/article/details/105939024
p