【模拟赛】 2020.5.6

T1三向城
只有我是60pts
画一下 \(7\) 个点的图会发现这是颗二叉树,找两个点的最短路径就是找 \(LCA\),当没找到 \(LCA\) 的时候就让两个数中大的一个除以 \(2\),对于 \(10^9\) 他的深度不超过 \(30\) 所以一次暴跳找 \(LCA\) 不超过 \(60\) 次,询问只有 \(10^4\) 可以过。

#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>

inline void read(int &T) {
	int x=0;bool f=0;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=!f;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	T=f?-x:x;
}

int n,x,y;

int main() {
	read(n);
	for(int i=1,ans=0;i<=n;++i) {
		read(x),read(y);
		while(x!=y) {
			if(x<y) y/=2;
			else x/=2;
			++ans;
		}
		std::cout<<ans<<'\n';
		ans=0;
	}
	return 0;
}

T2灵魂画师
期望dp。因为每个画纸初始颜色都一样,所以我们只对一张画纸求概率即可。设dp[i][j]为一张画纸经过 \(i\) 次操作变成了颜色 \(j\) 的概率。因为集合中每个元素不被选中的概率为 \(\frac{1}{2}\),所以dp[i][j]+=dp[i-1][j]/2。因为每个颜色被选中的概率率为 \(\frac{1}{c}\),所以dp[i][j * k%c]+=dp[i][j]/2c(选中了第k种颜色)。期望就等于dp[i][j] * j,因为和的期望等于期望的和,所以最后把期望加一下就是答案。

#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
#include<iomanip>

inline void read(int &T) {
	int x=0;bool f=0;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=!f;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	T=f?-x:x;
}

int n,k,c,maxn,cnt[101];
double dp[101][101];

int max(int a,int b) {
	return a>b?a:b;
}

int main() {
	read(n),read(c),read(k);
	for(int i=1,l,r;i<=k;++i) {
		read(l),read(r);
		for(int j=l;j<=r;++j) {
			++cnt[j];
			maxn=max(maxn,cnt[j]);
		}
	}
	dp[0][1]=1;
	for(int i=1;i<=maxn;++i) {
		for(int j=0;j<c;++j) {
			for(int k=0;k<c;++k) {
				dp[i][j*k%c]+=dp[i-1][j]/(2*c);
			}
			dp[i][j]+=dp[i-1][j]/2;
		}
	}
	double ans=0;
	for(int i=1;i<=n;++i) {
		for(int j=0;j<c;++j) {
			ans+=dp[cnt[i]][j]*j;
		}
	}
	std::cout<<std::fixed<<std::setprecision(3)<<ans<<'\n';
	return 0;
}
posted @ 2020-05-06 14:15  yu__xuan  阅读(163)  评论(0编辑  收藏  举报