2021.8.12 提高B组模拟赛

2021.8.12 2021.8.12 2021.8.12 模拟赛
目录:

T1.幻象
T2.树上摩托
T3.矩阵

T 1 : T1: T1幻象

在这里插入图片描述
L u o g u   l i n k \textcolor{pink}{Luogu~link} Luogu link

分析:

之前做过 赛时切
p i p_i pi为到 i i i的期望长度 f i f_i fi为到 i i i的期望分数
p i = ( p i − 1 + 1 ) × a i p_i=(p_{i-1}+1)\times a_i pi=(pi1+1)×ai
f i = f i − 1 + ( p i 2 − p i − 1 2 ) × a i f_i=f_{i-1}+(p_i^2-p_{i-1}^2)\times a_i fi=fi1+(pi2pi12)×ai
平方相减可以化成 ( p i − 1 + 1 ) 2 − p i − 1 2 = 2 × p i − 1 + 1 (p_{i-1}+1)^2-p_{i-1}^2=2\times p_{i-1}+1 (pi1+1)2pi12=2×pi1+1 直接平方相减也行

CODE:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e6+5;
int n,a[N];
double f[N],p[N];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		p[i]=(p[i-1]+1)*a[i]/100;
	}
	for(int i=1;i<=n;i++)
		f[i]=f[i-1]+(2*p[i-1]+1)*a[i]/100;
	printf("%.1lf",f[n]);
	return 0;
}

T 2 : T2: T2树上摩托

在这里插入图片描述

分析:

计算子树大小 s i z e size size 再枚举树大小 i i i 判断 s i z e size size i i i的倍数的节点数量为 n i \frac{n}{i} in即可
d f s dfs dfs会爆栈 要 b f s bfs bfs

CODE:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#pragma GCC optimize(2)
using namespace std;
const int N=1e6+5;
int n,tot,head[N],size[N],res,ans,cnt[N],fa[N],q[N];
struct node{
	int to,next;
}a[N<<1];
void add(int x,int y)
{
	a[++tot]=(node){y,head[x]};
	head[x]=tot; 
}
void bfs()
{
	int Head=1,tail=1;
	q[1]=1;
	while(Head<=tail)
	{
		int x=q[Head++];
		size[x]=1;
		for(int i=head[x];i;i=a[i].next)
		{
			int qwq=a[i].to;
			if(qwq==fa[x]) continue;
			fa[qwq]=x;
			q[++tail]=qwq;
		} 
	}
	for(int i=n;i>=1;i--)
	{
		int x=q[i];
		for(int j=head[x];j;j=a[j].next)
		{
			int qwq=a[j].to;
			if(qwq^fa[x]) size[x]+=size[qwq];
		}
	}
}
int main(){
	scanf("%d",&n);
	for(int i=1,x,y;i<n;i++)
	{
		scanf("%d%d",&x,&y);
		add(x,y); add(y,x); 
	}
	bfs();
	for(int i=1;i<=n;i++)
		cnt[size[i]]++;
	for(int i=1;i<=n;i++)
	{
		res=0;
		if(n%i!=0) continue;
		for(int j=1;j<=n/i;j++) 
			res+=cnt[i*j];
		if(res==n/i) ans++; 
	}
	printf("%d",ans);
	return 0;
} 

T 3 : T3: T3矩阵

在这里插入图片描述

分析:

将所有最小和谐矩阵加入堆
每次从堆中取出最小的和谐矩阵 扩展出最多四个新的和谐矩阵 即上下左右多 1 1 1行或 1 1 1列 注意判重 做 k k k次即可 最后 a n s ans ans u l l ull ull
在这里插入图片描述
就很好
在这里插入图片描述

CODE:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<set>
#pragma GCC optimize(2)
#include<cstring>
#define reg register
using namespace std;
typedef long long ll;
const int N=1005;
int n,m,Mina,Minb,k,a[N][N];
ll sum[N][N],ans;
struct Square{
	int x,y,x2,y2;
	ll Sum()const{return sum[x2][y2]-sum[x2][y-1]-sum[x-1][y2]+sum[x-1][y-1];}
	bool operator <(Square b)const{
		Square a=*this;
		if(a.Sum()!=b.Sum()) return a.Sum()<b.Sum();
		if(a.x!=b.x) return a.x<b.x;
		if(a.y!=b.y) return a.y<b.y;
		if(a.x2!=b.x2) return a.x2<b.x2;
		if(a.y2!=b.y2) return a.y2<b.y2;
		return 0;
	}
};
set<Square> Q;
int main(){
	scanf("%d%d%d%d%d",&n,&m,&Mina,&Minb,&k);
	for(reg int i=1;i<=n;i++)
	for(reg int j=1;j<=m;j++)
		scanf("%d",&a[i][j]);
	for(reg int i=1;i<=n;i++)
	for(reg int j=1;j<=m;j++)
		sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];
	for(reg int i=1;i<=n-Mina+1;i++)
	for(reg int j=1;j<=m-Minb+1;j++)
	{
		Square tmp=(Square){i,j,i+Mina-1,j+Minb-1};
		Q.insert(tmp); 
	} 
	k--;
	while(k--)
	{
		Square tmp=*Q.begin();
		Q.erase(tmp);
		if(tmp.x>1)
		{
			Square res=(Square){tmp.x-1,tmp.y,tmp.x2,tmp.y2};
			Q.insert(res);
		}
		if(tmp.y>1)
		{
			Square res=(Square){tmp.x,tmp.y-1,tmp.x2,tmp.y2};
			Q.insert(res);
		}
		if(tmp.x2<n)
		{
			Square res=(Square){tmp.x,tmp.y,tmp.x2+1,tmp.y2};
			Q.insert(res);
		}
		if(tmp.y2<m)
		{
			Square res=(Square){tmp.x,tmp.y,tmp.x2,tmp.y2+1};
			Q.insert(res);
		}
	}
	Square ans=*Q.begin();
	printf("%u",ans.Sum());
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值