练习--蓝桥杯2022省赛(灌水)

文章介绍了三个IT竞赛中的算法题目:C题要求计算整数两两相乘之和,使用前缀和方法;D题涉及选数异或查询,通过构造f数组求解;E题是关于爬树甲壳虫的期望时间计算,运用概率模型。
摘要由CSDN通过智能技术生成

C题 求和

给定 n 个整数 a1, a2, · · · , an ,求它们两两相乘再相加的和,即 S = a1 · a2 + a1 · a3 + · · · + a1 · an + a2 · a3 + · · · + an-2 · an-1 + an-2 · an + an-1 · an.

解法

前缀和秒了

D题  P8773 [蓝桥杯 2022 省 A] 选数异或选数异或

 给定一个长度为 n 的数列 A1, A2, · · · , An 和一个非负整数 x,给定 m 次查询, 每次询问能否从某个区间 [l,r] 中选择两个数使得他们的异或等于 x 。

思路

首先 a^b=x <=> a=b^x

对于数组a中任意数ai,其对应唯一的另一数x^ai。也就是说,每个a[i]都只有唯一一个可行解。

那么,可以使用数组f[r] 记录区间[1,r]中所有合法组合的最大左端点的下标,注意 f[r]对应的右端点可以不是r

那么对每次询问[l,r] 只要判断区间 [f[r],r] 是否在 [l,r] 中即可,也就是l和f[r]比较。

对于数组f[],显然f[i]=max(f[i-1],xxx)。问题转化为如何求xxx。

从左往右遍历数组a,如果a[i]^x,在[1,i]中出现过(设为j),f[i]=max( f[i-1],j )

用一个map储存 a[i] 和 i 的对应关系,即 map[a[i]]=i

f[i]=max(f[i-1],mp[x^a[i]]); 

#include<iostream>
#include<map>
#include<vector>
using namespace std;
#define imp map<int,int>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
int main(){
	int n,m,x;
	cin>>n>>m>>x;
	vector<int> a(n+1),f(n+1);
	imp mp;
	FOR(i,1,n){
		cin>>a[i];
		f[i]=max(f[i-1],mp[x^a[i]]);
		mp[a[i]]=i;
	}
	int l,r;
	FOR(i,1,m){
		cin>>l>>r;
		if(l<=f[r])cout<<"yes\n";
		else cout<<"no\n";
	}
} 

E题 P8774 [蓝桥杯 2022 省 A] 爬树的甲壳虫

有一只甲壳虫想要爬上一颗高度为 n 的树,它一开始位于树根, 高度为 0,当它尝试从高度 i−1 爬到高度为 i 的位置时有 Pi​ 的概率会掉回树根, 求它从树根爬到树顶时, 经过的时间的期望值是多少。

数学题

思路

设 f[i]为 i 到 n 花费的时间,p[i]为从i到i+1掉下去的概率,显然f[n]=0。

f[i] = p[i+1]*f[0]+ (1+ (1-p[i+1])*f[i+1] )

 分别带入直到只有f[0]和f[n]得到

f[0]​=∏(1−p[i​])f[n​]+f[0​]∑p[i​]​​∏(1−pj​)+∑​∏​(1−pj​)

因为f[n]=0,f[0]= ∑​∏​(1−pj​) / (1-∑p[i​]​​∏(1−pj​))

不会写逆元,寄

  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值