牛客第四场 题解_Frank_Star的博客-程序员秘密

技术标签: 算法  c++  多校联赛  acm竞赛  icpc  数据结构  

牛客第四场 题解
比赛传送门

by fn

比赛概况
过了四道,感觉还可以,算正常发挥啦。


签到题

F题 Just a joke 只是一个玩笑

考察内容
思维

分析
对于第一种操作, 会使得边数 -1
对于第二种操作, 会删除一棵树,使得点数 -k, 边数 -(k-1)

任何一种操作都会使得点数+边数的和减少一个奇数, 所以答案只跟 n+m 的奇偶性有关

#include<bits/stdc++.h>
using namespace std;
int n,m;
int ans=0;
int main(){
    
	cin>>n>>m;
	for(int i=1;i<=m;i++){
    
		int u,v;
		cin>>u>>v;
	}
	
	if((n+m)%2==0) cout<<"Bob"<<endl; //
	else cout<<"Alice"<<endl; 
	return 0;
}

基本题

C题 LCS 最长公共子串

题目大意
构造长为 n n n 的字符串s1,s2,s3, 使s1,s2的最长公共子串长 a a a, s2,s3的最长公共子串长 b b b , s1,s3的最长公共子串长 c c c

考察内容
暴力

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1010;
ll n,m,a,b,c;
char s[4][N];
int main(){
     //
	cin>>a>>b>>c>>n;
	
	int min1=min(a,min(b,c));
	
	if(n<a+b+c-2*min1){
     // 判断可行性 
		puts("NO");
		return 0;
	}
	
	for(int i=1;i<=3;i++){
     // 初始化 
		for(int j=1;j<=n;j++){
    
			s[i][j]=' ';
		}
	}

	if(min1==a){
     // a最小 
		for(int i=1;i<=a;i++){
    
			s[1][i]='a';
			s[2][i]='a';
			s[3][i]='a';
		}
		if(b<c){
    
			for(int i=a+1;i<=b;i++){
    
				s[2][i]='b';
				s[3][i]='b'; 
			}
			for(int i=b+1;i<=c+(b-a);i++){
    
				s[1][i]='c';
				s[3][i]='c';
			}
		}
		else{
     // b>=c
			for(int i=a+1;i<=c;i++){
    
				s[1][i]='c';
				s[3][i]='c'; 
			}
			for(int i=c+1;i<=b+(c-a);i++){
    
				s[2][i]='b'; //
				s[3][i]='b';
			}
		}
	}
	else if(min1==b){
    
		for(int i=1;i<=b;i++){
    
			s[1][i]='b';
			s[2][i]='b';
			s[3][i]='b';
		}
		if(a<c){
    
			for(int i=b+1;i<=a;i++){
    
				s[1][i]='a';
				s[2][i]='a'; 
			}
			for(int i=a+1;i<=c+(a-b);i++){
    
				s[1][i]='c';
				s[3][i]='c';
			}
		}
		else{
     // a>=c
			for(int i=b+1;i<=c;i++){
    
				s[1][i]='c';
				s[3][i]='c'; 
			}
			for(int i=c+1;i<=a+(c-b);i++){
    
				s[1][i]='a';
				s[2][i]='a';
			}

		}
		
	}
	else{
     // min1==c 
		for(int i=1;i<=c;i++){
    
			s[1][i]='c';
			s[2][i]='c';
			s[3][i]='c';
		}
		if(a<b){
    
			for(int i=c+1;i<=a;i++){
    
				s[1][i]='a';
				s[2][i]='a'; 
			}
			for(int i=a+1;i<=b+(a-c);i++){
    
				s[2][i]='b';
				s[3][i]='b';
			}
		}
		else{
     // a>=b
			for(int i=c+1;i<=b;i++){
    
				s[2][i]='b';
				s[3][i]='b'; 
			}
			for(int i=b+1;i<=a+(b-c);i++){
    
				s[1][i]='a';
				s[2][i]='a';
			}

		}
		
	}
	
	// 填满空格 
	for(int i=1;i<=3;i++){
    
		for(int j=1;j<=n;j++){
    
			if(s[i][j]==' ') s[i][j]='c'+i;
		}
	}
	
	// 输出 
	for(int i=1;i<=3;i++){
    
		for(int j=1;j<=n;j++){
    
			cout<<s[i][j];
		}
		puts("");
	}
	return 0;
}

J题 Average 平均值

题目大意
给定序列 a,b, 找 a 的一个长度至少为 x 的平均值最大的子区间和 b 的一个长度至少为 y 的平均值最大的子区间。输出两个平均值的和。

考察内容
二分,前缀和

分析
poj2018,经典二分+前缀和,套板子。注意一下边界和精度。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5+10; //
int n,F;
double ans;
double a[maxn+5],b[maxn+5],sum[maxn+5];

bool ok(double mid){
    
	for(int i=1; i<=n; ++i){
    
		b[i]=a[i]-mid;
	}
	for(int i=1; i<=n; ++i){
    
		sum[i] = sum[i-1] + b[i];
	}
	double min_val = 1e10,ans=-1e10;
	for(int i=F; i<=n; ++i){
    
		min_val = min(sum[i-F], min_val); // 前面(0~i-F)的最小前缀和 
		ans = max(ans, sum[i]-min_val);
	}
	return ans>=0;
}
void solve(){
    
	double l=-1,r=100010,eps=1e-8; // 2分平均数 
	while(r-l>eps){
    
		double mid = (l+r)/2;
		if(ok(mid)) l=mid;
		else r=mid;
	}
	ans+=(l+r)/2; // 累加答案 
}

int main(){
    
	int m,y;
	cin>>n>>m>>F>>y;
	for(int i=1; i<=n; ++i){
    
		scanf("%lf",&a[i]);
	}
	solve();
	
	n=m;
	F=y;
	for(int i=1; i<=n; ++i){
    
		scanf("%lf",&a[i]);
	}
	solve();
	
	printf("%.8f",ans);
	return 0;
} 

I题 Inverse Pair 逆序对

题目大意
给定全排列 a a a ,对每个元素可以执行+1的操作或不变,求操作后最少的逆序对对数。

分析
考虑一下什么情况下 +1 这个操作会让逆序对变少

如果 x 在 x+1 的后面, 则我们把 x 这个数+1, x+1 不变, 就能让逆序对减少 1

那考虑建一张图, 如果 x 在 x+1 后面则连边 (x,x+1), 最后会得出若干条链, 一条长度为 L 的链我们最多用它减少 L/2 个逆序对

时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)

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

long long n,a[200005],tr[200005],t[200005],ans;
void add(long long x) {
    
	for(long long i=x;i<=n+1;i+=i&-i) {
    
		tr[i]++;
	}
	return;
}
int ask(long long x) {
    
	long long ans=0;
	for(long long i=x;i;i-=i&-i) {
    
		ans+=tr[i];
	}
	return ans;
}
int main() {
    
	scanf("%lld",&n);
	for(int i=1;i<=n;i++) {
    
		scanf("%lld",&a[i]);
		if(t[a[i]+1]==1) {
    
			ans+=ask(n+1)-ask(a[i]+1);
			add(a[i]+1);
		} else {
    
			t[a[i]]=1;
			ans+=ask(n)-ask(a[i]);
			add(a[i]);
		}
	}
	printf("%lld",ans);
 	return 0;
}

进阶题

E题 Tree Xor 树异或

题目大意
给定一棵有 n n n 个结点的树,每个结点记录一个权重 w w w。给定每个结点权重的区间,每一条边上记录相邻两个结点进行异或后的值。求树上有多少种可能的权重分配。

考察内容
数据结构(线段树 或 字典树)

分析
先令 w [ 1 ] = 0 w[1]=0 w[1]=0, 解出剩下的 w w w
之后可以发现, 如果要 w [ 1 ] = a w[1]=a w[1]=a , 那么剩下的 w w w 都会 x o r xor xor a a a
所以就变成了求解合法的 a a a 的数量, 限制有 n n n 个不等式, 形式为

l [ i ] < = w [ i ] l[i] <= w[i] l[i]<=w[i] x o r xor xor a < = r [ i ] a<=r[i] a<=r[i] , i = 1 , 2 , 3 , 4 , . . . , n i=1,2,3,4,...,n i=1,2,3,4,...,n

也就是 a a a i n in in { x x x x o r xor xor w [ i ] w[i] w[i] | l [ i ] < = x < = r [ i ] l[i]<=x<=r[i] l[i]<=x<=r[i] }

考虑把 [ L [ i ] , R [ i ] ] [L[i] , R[i]] [L[i],R[i]] x o r xor xor w [ i ] w[i] w[i] 分成若干个连续的区间。

我们可以利用 [ 0 , 2 30 − 1 ] [0,2^{30-1}] [0,2301] 的线段树(或者字典树), 把 [ L [ i ] , R [ i ] ] [L[i] , R[i]] [L[i],R[i]] 分成 O ( l o g W ) O(logW) O(logW) 个连续的区间, 且每个区间的形式是 : k . . . 30 k...30 k...30 位相同, 0... k − 1 0...k-1 0...k1 位是 0 0 0 2 k − 1 2^{k-1} 2k1, 这样的区间异或上 w [ i ] w[i] w[i] 后仍然还是一个区间

之后我们对这 n n n 组区间求个交, 就可以得出答案的区间
时间复杂度 : O ( n l o g 2 n ) O(nlog^2n) O(nlog2n)

#include<bits/stdc++.h>
using namespace std;
const int M=8000005;

int son[M][2];
bool flag[M];
int rt=1,tot=1;
int l[100005],r[100005];
struct ed{
    
	int x,l,nx;
}e[100005*2];
int nx[100005],ecnt=1;
void add(int x,int y,int l){
    
	e[ecnt]=(ed){
    y,l,nx[x]};
	nx[x]=ecnt++;
}
void del(int t,int v){
    
	int p=rt;
	for (int i=30;i>=t;i--){
    
		if (!son[p][(v>>i)&1])son[p][(v>>i)&1]=++tot;
		p=son[p][(v>>i)&1];
	}
	flag[p]=1;
}
void chk(int l,int r,int x){
    
	int t1=l^x,t2=r^x;
	for (int i=30;i>=0;i--){
    
		if ((l>>i)&1)del(i,t1^(1<<i));
		if (!((r>>i)&1))del(i,t2^(1<<i));
	}
}

void dfs(int f,int x,int v){
    
	chk(l[x],r[x],v);
	for (int i=nx[x];i;i=e[i].nx)if (e[i].x!=f){
    
		dfs(x,e[i].x,v^e[i].l);
	}
}
int res;
void dfs1(int d,int x,int v){
    
	if (flag[x])return;

	if ((!x)){
    
		res+=(1<<(d+1));
		return ;
	}
	dfs1(d-1,son[x][0],v);
	dfs1(d-1,son[x][1],v+(1<<d));
}
int calc(){
    
	dfs1(30,rt,0);
	return res;
}
int n;
int main(){
    
	scanf("%d",&n);
	for (int i=1;i<=n;i++){
    
		scanf("%d%d",&l[i],&r[i]);
	}
	for (int i=1;i<n;i++){
    
		int x,y,t;
		scanf("%d%d%d",&x,&y,&t);
		add(x,y,t);
		add(y,x,t);
	}
	dfs(1,1,0);
	printf("%d\n",calc());
}


B题 Sample Game 样品游戏

题目大意
给定范围 n n n 和生成每个数字的概率 p p p ,不断生成 [ 1 , n ] [1,n] [1,n] 范围的随机数,如果当前生成的数字大于等于之前所有的数字就继续生成。求生成数字个数平方的期望。

考察内容
概率与数学期望

结论
答案是 2 f ′ ( 1 ) + f ( 1 ) 2f^{'}(1)+f(1) 2f(1)+f(1),其中 f ( 1 ) = ∏ i = 1 n 1 1 − p i f(1)=\prod \limits_{i=1}^n\frac{1}{1-p_{i}} f(1)=i=1n1pi1 , f ′ ( 1 ) = f ( 1 ) ∑ i = 1 n p i 1 − p i f^{'}(1)=f(1)\sum \limits_{i=1}^n\frac{p_{i}}{1-p_{i}} f(1)=f(1)i=1n1pipi

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

const int N=105;
const int mo=998244353;
int n,a[N],p[N],T[N],S;
int power(int x,int y){
     // 快速幂 
	int s=1;
	for (;y;y/=2,x=1ll*x*x%mo)
		if (y&1) s=1ll*s*x%mo;
	return s;
}
int main(){
    
	scanf("%d",&n);
	for (int i=1;i<=n;i++) scanf("%d",&a[i]), S+=a[i]; 
	
	for (int i=1;i<=n;i++) a[i]=1ll*a[i]*power(S,mo-2)%mo;
	S=1;
	for (int i=1;i<=n;i++){
    
		p[i]=1ll*a[i]*S%mo*power(1+mo-a[i],mo-2)%mo;
		S=(S+p[i])%mo;
	}
	for (int i=n;i>=1;i--){
    
		int S=1;
		for (int j=i+1;j<=n;j++)
			S=(S+1ll*a[j]*T[j])%mo;
		T[i]=1ll*S*power(1+mo-a[i],mo-2)%mo;
	}
	int ans=1;
	for (int i=1;i<=n;i++)
		ans=(ans+1ll*a[i]*T[i])%mo;
	for (int i=1;i<=n;i++)
		ans=(ans+2ll*p[i]*T[i])%mo;
	cout<<ans<<endl;
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_51937688/article/details/119117172

智能推荐

CVE-2009-0927漏洞分析_A1exxx的博客-程序员秘密

1 CVE-2009-0927简介 Adobe Reader 是非常流行的 PDF 文件阅读器,在其 Collab 对象的 getIcon()函数中存在一 个缓冲区溢出漏洞。同时由于 PDF 文档中支持内嵌的 JavaScript,攻击者可以通过在 PDF 文档 中植入恶意的JavaScript来向getIcon()函数传递特制的参数以触发溢出漏洞,并结合Heap Spray 攻...

java定时器quartz开发_普通网友的博客-程序员秘密

前言今日博主听闻,现在很多培训出来的应届生薪资都赶上了摸爬滚打两三年的朋友,讲道理,这说不过去啊作为同行来说,这个行业发展很快,技术更新很快,淘汰也很快,千万不要再找借口了,想吃这碗饭不如好好思考如何提升自己的技术,提高自己的核心竞争力。下面博主给大家分享一波十月份精选的互联网大厂Java核心面试题,透过面试题来分析自己所掌握的技术栈与大厂所需的差距,判断面试难易程度,从而进一步明确自己学习的方向。Maven权威指南首先,本书适合所有Java程序员阅读。由于自动化构建、依赖管理等问题并不只存在于J

工具使用Tips_软件中tips_宇夜风啸的博客-程序员秘密

工具使用Tips工具使用TipsWebstorm字体自定义:Sublime插件安装:Eclipse添加server插件Eclipse添加PyDev插件持续记录中。。。。。Webstorm字体自定义:代码字体 File -&amp;gt; Setting -&amp;gt; Editor -&amp;gt; Font 可考虑选择 “Goudy Old Style”,英文的很漂亮,字...

灰色关联度分析_五千年的反射弧的博客-程序员秘密

灰色系统理论是由著名学者邓聚龙教授首创的一种系统科学理论(Grey Theory),其中的灰色关联分析是灰色关联度分析(Grey Relation Analysis,GRA),是一种多因素统计分析的方法。简单来讲,就是在一个灰色系统中,我们想要了解其中某个我们所关注的某个项目受其他的因素影响的相对强弱,再直白一点,就是说:我们假设以及知道某一个指标可能是与其他的某几个因素相关的,那么我们想知道这个指标与其他哪个因素相对来说更有关系,而哪个因素相对关系弱一点,依次类推,把这些因素排个序,得到一个分析结果,我们

面试题(两个栈实现一个队列和两个队列实现一个栈)_zhuohaiyy的博客-程序员秘密

面试题(判断元素出栈入栈顺序的合法性。) 面试题(实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1))1,两个栈实现一个队列我们知道栈是后进先出的,而队列是先进先出的 我们创建两个栈input(输入栈),output(输出栈) 我们用input(输入栈)来负责入队,而output(输出栈)来负责出队(反向) 出队是,如果output不为空,

360无线网卡驱动 linux,磊科nw360无线网卡如何安装linux下驱动_懒床上的猫的博客-程序员秘密

补充: 刚才又试了下,发现有点搞笑的是,我用的mageia 1自带了驱动,ifconfig就看到了2块无线网卡~ 无奈啊。试了下能用.... 就是不知道能不能连加密网络。不知道什么原因我本子自带的intel wifi link 1000连不上wep或者wpa加密的网络。也许是配置有误吧。你用的debian... debian或许没有这么好的硬件支持吧.... 插上试了,没识别?下面是原来的回答...

随便推点

coreldraw x4忽略视图样式补丁_Coreldraw x4忽略颜色样式和视图样式补丁_汽配搬运工的博客-程序员秘密

打上《Coreldraw x4忽略颜色样式和视图样式补丁》后,可以在很大程度上解决Coreldraw打开文件超慢的问题,大大提升coreldraw x4的运行速度和反应速度。精准的来讲这是一个Coreldraw加速补丁比较精准。Coreldraw加速补丁功能:提升coreldraw x4的运行速度/反应速度,为Coreldraw加速,加速补丁用于 CorelDRAW X4,读取CDR文件时,忽略文...

BitCoinRpcTool_songbinchao的博客-程序员秘密

package io.mjoy.coin.service.tool;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONArray;import com.alibaba.fastjson.JSONObject;import com.alibaba.fastjson.serializer.SerializerFe...

写入数据mysql_mysql数据写入_xutingck的博客-程序员秘密

import mysql.connectormydb = mysql.connector.connect(host = ‘localhost’, user = ‘root’, passwd = ‘001828abc.’, database = ‘gllogs’)mycursor = mydb.cursor()#mycursor.execute(“create database gllogs”)#print(mycursor.execute(“show databases”))mycursor.ex

IDEA搭建SpringBoot项目时,本地仓库有jar包,pom中spring-boot-maven-plugin还是报错的方法_springboot引入依赖报错,但本地仓库有包_鄙下的博客-程序员秘密

入门spring-boot,根据网上的教程搭建项目的时候,发现这两个地方报错,找到pom.xml中这个显示not found,网上找了很多方法,特意检查了一下maven 的配置,没什么问题,然后在本地仓库中发现有这个的jar包网上很多什么删除-remote.repositories文件什么的,都试了一遍还是没什么用,最后直接删除了仓库的这个jar包,重新重新刷新了一下,然后就...

ofo融资迷局:滴滴、阿里、戴威的三角博弈_sweetfire的博客-程序员秘密

ofo仍在努力续命。9月5日,据多家媒体报道,ofo将完成E2-2轮融资,融资数额达数亿美元,由蚂蚁金服领投,滴滴跟投。据说融资消息是从ofo内部传出来的。全天候科技就此向多个相关方求证,ofo公关回复“好像是,具体细节不清楚”,滴滴方面“不予置评”,蚂蚁金服也“不予置评”。关键相关方的模糊回应令这轮融资消息真假难辨。全天候科技就此询问多位接近ofo和蚂蚁金服的投资人士,他们均表示...

海思3559 2lane*8 模式_视频编码中的8lane是什么意思_羽霍飞的博客-程序员秘密

连接方式是fpga 输出5组2 data lane+1lane clk的lvds信号给3559,3559设置为2lane*8 的模式进行数据接收。使用Hi3559A V100R001C02SPC020 版本的sdk包进行开发是,发现数据接收不到显示接收不到同步头,打印信息如下:cat /proc/umap/hi_mipi Module: [MIPI], Build Time: [Dec 21 2018, 17:12:09]-----MIPI LANE DIVIDE MODE-----------

推荐文章

热门文章

相关标签