11.21比赛题解

神鹰中学

让你飞起来

1.拓扑排序

2.简单分析下题意:给出一些大小关系,问根据这些关系能不能确定排名,如果不能, 判断是信息不完全,还是信息冲突。

3.大概思路:

考虑出现冲突的情况: 当且仅当图中存在环,才会出现冲突,如:a > b, b > c, c > a, 则是冲突, 这种情况可在拓扑排序时确定。简要说一下拓扑排序:每次在有向图中找出一个入度为0的节点,加入队列,并删除该节点发出的所有边(在用队列实现的过程中,可直接把与之相连的节点的入度-1, 最后,如果还剩下节点未排序,则表示出现了环,因为环中没有节点入度为0。

考虑出现信息不完全的情况:如果某一时刻,有多个入度为0的点,那么信息肯定不完全,因为这样就没法确定这些入度为0的点之间的先后关系。

那么如何处理相等的情况:这种情况不能用拓扑排序来处理,因为,如果把a==b==c处理成a>b>c的话,那么有可能出现e<a, e > b是正确的情况, 所以,正确的方法是把相等的节点用并查集处理成一个节点。

the end...

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int fa[N],in[N],A[N],B[N],n,m,sum;
char op[N];
vector<int> G[N];
int find(int x){
    if(x!=fa[x]){
        fa[x]=find(fa[x]);
    }
    return fa[x];
}
void topSort(){
    queue<int> Q;
    bool uncertain=false;
    for(int i=0;i<n;i++){
        if(in[i]==0&&find(i)==i) Q.push(i);
    }
    while(!Q.empty()){
        if(Q.size()>1){
            uncertain=true;
        }
        int now=Q.front();Q.pop();
        sum--;
        for(int i=0;i<G[now].size();i++){
            if(--in[G[now][i]]==0){
                Q.push(G[now][i]);
            }
        }
    }
    if(sum>0) puts("fantasy");
    else if(uncertain) puts("dark");
    else puts("deep");
}
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        for(int i=0;i<n;i++){
            fa[i]=i,in[i]=0;
            G[i].clear();
        }
        sum=n;
        for(int i=0;i<m;i++){
            int a,b;
			char s[3];
			scanf("%d%s%d",&a,s,&b);
            op[i]=s[0],A[i]=a,B[i]=b;
            if(s[0]=='='){
                int fx=find(a),fy=find(b);
                if(fx!=fy){
                    fa[fx]=fy;
                    sum--;
                }
            }
        }
        for(int i=0;i<m;i++){
            if(op[i] == '=') continue;
            int a=find(A[i]),b=find(B[i]);
            if(op[i]=='>'){
                G[a].push_back(b);
                in[b]++;
            }
            else{
                G[b].push_back(a);
                in[a]++;
            }
        }
        topSort();
    }
    return 0;
}

Inferno

1.贪心

2.题意:给一个仅包含 −1,0,1 的序列 a。在为 0 的位置中选 k 个更改为 1,其余更改为 −1,使得最大子段和最大,求最大子段和的最大值。

3.思路:

如果想让最大子段和最大,尽可能的把一串连续的 0 变为 1,插入一个 −1 一定很劣,因为会把一串前缀和单调增的序列变的不单调增,而子段和可以这样理解:画出一个前缀和的函数图像,可以认为子段和就是在函数上任取两点的函数值相减的绝对值。如果前缀和函数是单调增的,那最大子段和就很显然;倘若出现一个负数,前缀和必定会下降,把区间断成两部分,这样一定很劣。

可以去枚举最大子段和的左端点,然后往右边改 k 个 0。但又一个问题,不一定能改到 k 个 0 ,于是分类讨论右端点是否在这 k 个 0 内部。如果在的话那很简单,用单调队列维护前缀和加上前缀 0 的个数;如果不在就用前缀和减去前缀 0 的个数。

#include<bits/stdc++.h>
using namespace std;
const int N=1e7+10;
int n,k,a[N],lst[N],zero[N],cnt;
int sum1[N],sum2[N],mini[N];
void find_min(){
	deque<pair<int,int> >dq;
	for(int i=1;i<=n;++i){
		while(!dq.empty()&&sum1[i]<=dq.front().first)dq.pop_front();
		dq.push_front(make_pair(sum1[i],i));
		while(!dq.empty()&&dq.back().second<zero[max(0,lst[i]-k+1)])dq.pop_back();
		mini[i]=dq.size()?dq.back().first:0;
	}
	return;
}
int main(){
	cin>>n>>k;
	int lstt=0;
	for(int i=1;i<=n;++i){
		cin>>a[i];
		sum1[i]=sum1[i-1];
		sum2[i]=sum2[i-1];
		if(a[i]==0){
			sum1[i]++;
			sum2[i]--;
			zero[++cnt]=i;
			lstt=cnt;
		}
		else{
			sum1[i]+=a[i];
			sum2[i]+=a[i];
		}
		lst[i]=lstt;
	}
	find_min();
	int maxn=1,minii=0;
	lstt=0;
	for(int i=1;i<=n;++i){
		int x=max(zero[max(0,lst[i]-k+1)]-1,0);
		for(int j=lstt;j<=x;++j)minii=min(minii,sum2[j]);
		lstt=x;
		int ans=max(sum1[i]-mini[i],sum1[i]-sum1[max(0,zero[max(0,lst[i]-k+1)]-1)]+sum2[max(zero[max(0,lst[i]-k+1)]-1,0)]-minii);
		maxn=max(maxn,ans);
	}
	cout<<maxn;
	return 0;
}

New Year Tree

1.线段树+dfs

2.要用到dfs序。本质上就是一棵树的先序遍历,所谓先序遍历就是先遍历根,然后遍历左子节点,最后遍历右子节点。需要把dfs序存在pos数组中,并把每个节点第一次遍历到的时间点和第二次遍历到的时间点存到in和out数组中,这样就成功地把一棵树转换为了线性结构。对一棵子树进行操作时,只需对这棵子树的根节点两次遍历到的时间戳中间的部分进行操作即可。

用dfs序,也就是pos数组对线段树进行操作,需要用到状态压缩,要把颜色压缩成二进制数到线段树中,所以要开long long。接下来基本上都是线段树区间修改,区间查询的模板了。需要注意的是,查询出来的值是一个经过状压后的数,我把它分解。可以借鉴树状数组的思想,即每次减去一个lowbit(一棵树上有数值的节点的最低位,不会的话可以先去学习一下树状数组,这里不再过多赘述)再让ans++,因为状压后只有0和1,有值的话一定是1。ans就是最后的答案。

#include<bits/stdc++.h>
using namespace std;
const int N=400010;
typedef long long ll;
struct node{
	ll v,next;
}edge[N<<2];
ll head[N],tot,tim;
ll in[N],out[N],pos[N];
ll a[N];
ll ans[N<<2],lazy[N<<2];
void dfs(ll x,ll fa){
	tim++;
	in[x]=tim;
	pos[tim]=x;
	for(ll i=head[x];i;i=edge[i].next){
		ll y=edge[i].v;
		if(y==fa) continue;
		dfs(y,x);
	}
	out[x]=tim;
}
void add(ll x,ll y){
	tot++;
	edge[tot].v=y;
	edge[tot].next=head[x];
	head[x]=tot;
}
void pushup(ll rt){
	ans[rt]=ans[rt<<1]|ans[rt<<1|1];
}
void pushdown(ll rt){
	if(lazy[rt]!=0){
		lazy[rt<<1]=lazy[rt];
		lazy[rt<<1|1]=lazy[rt];
		ans[rt<<1]=lazy[rt];
		ans[rt<<1|1]=lazy[rt];
		lazy[rt]=0;
	}
}
void build(ll l,ll r,ll rt){
	if(l==r){
		ans[rt]=1ll<<(a[pos[l]]);
		return;
	}
	ll mid=(l+r)>>1;
	build(l,mid,rt<<1);
	build(mid+1,r,rt<<1|1);
	pushup(rt);
}
void update(ll L,ll R,ll x,ll l,ll r,ll rt){
	if(L<=l&&r<=R){
		ans[rt]=1ll<<x;
		lazy[rt]=1ll<<x;
		return; 
	}
	pushdown(rt);
	ll mid=(l+r)>>1;
	if(L<=mid) update(L,R,x,l,mid,rt<<1);
	if(R>mid) update(L,R,x,mid+1,r,rt<<1|1);
	pushup(rt);
}
ll query(ll L,ll R,ll l,ll r,ll rt){
	if(L<=l&&r<=R)
		return ans[rt];
	pushdown(rt);
	ll mid=(l+r)>>1;
	ll res=0;
	if(L<=mid) res|=query(L,R,l,mid,rt<<1);
	if(R>mid) res|=query(L,R,mid+1,r,rt<<1|1);
	return res;
}
ll lowbit(ll k){
	return k&(-k);
}
ll getsum(ll x){
	ll ans=0;
	for(ll i=x;i>0;i-=lowbit(i))
		ans++;
	return ans;
}
int main(){
	ll n,m,p,v,c;
	scanf("%lld%lld",&n,&m);
	for(ll i=1;i<=n;i++)
		scanf("%lld",&a[i]);
	for(ll i=1;i<n;i++){
		ll x,y; 
		scanf("%lld%lld",&x,&y);
		add(x,y);
		add(y,x);
	}
	dfs(1,0);
	build(1,n,1);
	for(ll i=1;i<=m;i++){
		scanf("%lld",&p);
		if(p==1){
			scanf("%lld%lld",&v,&c);
			update(in[v],out[v],c,1,n,1);
		}
		else{
			scanf("%lld",&v);
			ll num=query(in[v],out[v],1,n,1);
			printf("%lld\n",getsum(num));
		}
	}
	return 0;
}

Levels and Regions

1.斜率优化dp(也可以是李超线段树)

2.题意:将n个数分成k组,对于任意一组取其中第i个数的概率为t[k]/∑t[k],求分组后取完所有数的最小期望。

3.f[i][j]表示把前j位分成i组所能最大优化的期望。

用s[i]记录t[i]前缀和,用p[i]记录t[i]倒数的前缀和。

于是得到DP方程:f[i][j]=max(f[i−1][k]+s[k]∗(p[j]−p[k]))

关于DP方程作出如下解释:

1.第ii组的状态只与第i−1组有关,需在第二维枚举k找最优解;

2.由于取第i组中第k个数的概率为t[k]/s[k],期望为s[k]/t[k],则分组后“被优化”的期望为s[k]∗(p[j]−p[k])

我们发现这样写肯定要超时,由于方程中仅有max函数,想到使用斜率优化加速。

考虑f[i][a]和f[i][b]的值,设f[i][a]>f[i][b],

则可得到f[i−1][a]+s[a]∗(p[j]−p[a])>f[i−1][b]+s[b]∗(p[j]−p[b])

设f[i−1][a]−s[a]∗p[a]=y(a),拆项移项得到y(a)−y(b)<(s[b]−s[a])∗p[j]。

#include<bits/stdc++.h>
#define int long long
#define inf 10000000000000000
using namespace std;
const int maxn=200005,maxm=55;
int i,j,k,m,n,l,r;
int a[maxn],suma[maxn],q[maxn];
double b[maxn],c[maxn],sumb[maxn],sumc[maxn],f[maxm][maxn];
inline int x(int p){
	return suma[p];
}
inline double y(int p,int c){
	return f[c-1][p]+1.0*suma[p]*sumb[p]-sumc[p];
}
inline double slope(int a,int b,int c){
	if(x(a)==x(b))
		return y(a,c)>y(b,c)? inf:-inf;
	return 1.0*(y(a,c)-y(b,c))/(x(a)-x(b));
}
signed main(){
	scanf("%lld%lld",&n,&m);
	for(i=1;i<=n;i++){
		scanf("%lld",&a[i]);
		suma[i]=suma[i-1]+a[i];
		b[i]=1.0/a[i],sumb[i]=sumb[i-1]+b[i];
		c[i]=1.0*suma[i]/a[i],sumc[i]=sumc[i-1]+c[i];
	}
	for(i=1;i<=n;i++)
		f[0][i]=inf;
	for(i=1;i<=m;i++){
		l=1,r=0;
		q[++r]=0;
		for(j=1;j<=n;j++){
			while(l<r&&slope(q[l+1],q[l],i)<=sumb[j])
				l++;
			f[i][j]=f[i-1][q[l]]+sumc[j]-sumc[q[l]]-suma[q[l]]*(sumb[j]-sumb[q[l]]);
			while(l<r&&slope(j,q[r-1],i)<=slope(q[r],q[r-1],i))
				r--;
			q[++r]=j;
		}
	}
	printf("%.10lf\n",f[m][n]);
	return 0;
}

总之,有点难度,有的题目不好理解,有的题没写出暴力,还得练练

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/920454.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【腾讯云产品最佳实践】腾讯云CVM入门技术与实践:通过腾讯云快速构建云上应用

目录 前言 什么是腾讯云CVM&#xff1f; 腾讯云CVM的技术优势 基于最佳技术实践&#xff0c;使用腾讯云CVM搭建应用 1. 开通CVM实例 2. 连接CVM实例 3. 配置Web环境 4. 部署PHP应用 腾讯云CVM行业应用案例&#xff1a;电商平台的双十一攻略 1. 弹性伸缩解决高并发问题…

mongodb多表查询,五个表查询

需求是这样的&#xff0c;而数据是从mysql导入进来的&#xff0c;由于mysql不支持数组类型的数据&#xff0c;所以有很多关联表。药剂里找药物&#xff0c;需要药剂与药物的关联表&#xff0c;然后再找药物表。从药物表里再找药物与成分关联表&#xff0c;最后再找成分表。 这里…

STL中vector实现——简单易懂版

本章内容 模拟实现 vector 的部分重要功能 1.迭代器的引入1.1 之前写法1.2 STL库中的写法 2.默认成员函数2.1构造与拷贝构造2.2拷贝赋值2.3析构函数 3.增删查改功能3.1插入3.2删除 4.为什么STL中vector没有find函数&#xff1f;5.&#x1f525;&#x1f525;迭代器失效场景&am…

Springboot + vue 健身房管理系统项目部署

1、前言 ​ 许多人在拿到 Spring Boot 项目的源码后&#xff0c;不知道如何运行。我以 Spring Boot Vue 健身房管理系统的部署为例&#xff0c;详细介绍一下部署流程。大多数 Spring Boot 项目都可以通过这种方式部署&#xff0c;希望能帮助到大家。 ​ 2、项目查看 ​ 首…

NuGet如何支持HTTP源

今天是2024年11月21号&#xff0c;最近更新了VisualStudio后发现HTTP的包源已经默认禁止使用了&#xff0c;生成时会直接报错。如下图&#xff1a; 官方也明确指出了要想使用HTTP包源的解决办法&#xff0c;这里就简单总结一下。 一、全局配置 1、全局NuGet包的配置文件路径在…

SpringBoot学习记录(四)之分页查询

SpringBoot学习记录&#xff08;四&#xff09;之分页查询 一、业务需求1、基本信息2、请求参数3、相应数据 二、传统方式分页三、使用PageHelper分页插件 一、业务需求 根据条件进行员工数据的条件分页查询 1、基本信息 请求路径&#xff1a; /emps 请求方式&#xff1a; …

JavaParser如何获取方法的返回类型

使用JavaParser 如何获取一个Java类中的某个方法的返回类型呢&#xff1f; 假如有一个如下的简单的Java 类&#xff1a; /*** Copyright (C) Oscar Chen(XM):* * Date: 2024-11-21* Author: XM*/ package com.osxm.ai.sdlc.codeparse.codesample;public class MyClass {public…

2024亚太杯国际赛C题宠物预测1234问完整解题思路代码+成品参考文章

中国宠物业发展趋势及预测模型 一、问题背景与研究目标 近年来&#xff0c;中国宠物业经历了快速发展&#xff0c;特别是在城市化进程加快、人口结构变化和消费水平提升的背景下&#xff0c;宠物作为家庭成员的角色变得愈发重要。根据相关数据&#xff0c;中国宠物数量&#…

Java实现离线身份证号码OCR识别

最近公司要求做离线身份证OCR功能&#xff0c;找了一圈总算是找到了&#xff0c;在这里对文档做个整理&#xff0c;方便后来者&#xff0c;感谢码龄23年博主的分享 系统&#xff1a;Windows11&#xff0c;红旗Linux Asianux8.1 文档中Linux全root用户操作&#xff1b;需先安装…

Gradle核心概念总结

这部分内容主要根据 Gradle 官方文档整理&#xff0c;做了对应的删减&#xff0c;主要保留比较重要的部分&#xff0c;不涉及实战&#xff0c;主要是一些重要概念的介绍。 Gradle 这部分内容属于可选内容&#xff0c;可以根据自身需求决定是否学习&#xff0c;目前国内还是使用…

鸿蒙网络编程系列50-仓颉版TCP回声服务器示例

1. TCP服务端简介 TCP服务端是基于TCP协议构建的一种网络服务模式&#xff0c;它为HTTP&#xff08;超文本传输协议&#xff09;、SMTP&#xff08;简单邮件传输协议&#xff09;等高层协议的应用程序提供了可靠的底层支持。在TCP服务端中&#xff0c;服务器启动后会监听一个或…

第5-1节:SpringBoot对SpringMVC的自动配置

我的后端学习大纲 SpringBoot学习大纲 1、SpringBoot对SpringMVC自动配置概览

Emacs进阶之插入时间信息(一百六十三)

简介&#xff1a; CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a; 多媒体系统工程师系列【…

嵌入式实验报告:家用计时器

实验目的和要求 1、实验目的 掌握STM32串口通信原理。学习编程实现STM32的UART通信掌握STM32中断程序设计流程。熟悉STM32固件库的基本使用。熟悉STM32定时器中断设计流程。2、实验要求 设计一个家用计时器,其功能如下: 利用串口设置计时时间,格式:XX:XX:X 例如01:59:…

【WRF理论第十二期】Registry.EM 文件详解

【WRF理论第十二期】Registry.EM 文件详解 Registry.EM 文件的作用Registry.EM 文件的结构Registry.EM 文件内容理解如何修改 Registry.EM 文件以输出特定变量WRF-Urban 修改 Registry.EM 文件以输出 UCM 相关变量1. 修改 Registry.EM 文件2. 重新编译 WRF 注意事项参考 在 WRF…

Midjourney 图生图,真人二次元保持一致性,场景多元可选择

Midjourney 拥有强大的图生图的功能&#xff0c;下面我们就来看一下&#xff0c;如何在我们的AceDataCloud网站上实现将照片切换成任意的二次元场景&#xff0c;同时保持人物的一致性。 我们可以按照如下的步骤去实现人物一致性。 下面我们来看看效果吧&#xff0c;原图如下。…

三种复制只有阅读权限的飞书网络文档的方法

大家都知道&#xff0c;飞书是一款功能强大的在线协作工具&#xff0c;可以帮助团队更高效地协作和沟通。越来越多的资料都在使用飞书文档&#xff0c;在使用飞书的过程中&#xff0c;发现很多文档没有复制权限&#xff0c;如果想要摘抄笔记&#xff0c;只能一个字一个字地敲出…

【GL003】TCP/IP 协议

目录 一、TCP/IP协议简介 二、TCP/IP协议的分层模型 2.1 OSI模型的七层框架 2.2 TCP/IP协议层&#xff08;四层&#xff09; 2.2.1 TCP/IP协议层与ISO模型 2.2.2 TCP/IP协议层的作用 三、TCP协议的报文格式 3.1 什么是报文 3.2 TCP报文 四、TCP的通信连接 4.1 TCP…

Spring WebFlux学习笔记(二)

目标 运行第一个spring webflux项目 官网操作 https://start.spring.io/ 依赖、工具 jdk 21、idea、maven 运行过程 将下载的代码直接导入到idea后运行 运行上个笔记的例子 注意 需要更改为MediaType.TEXT_EVENT_STREAM_VALUE 未完待续。。。

【YOLOv8】安卓端部署-2-项目实战

文章目录 1 准备Android项目文件1.1 解压文件1.2 放置ncnn模型文件1.3 放置ncnn和opencv的android文件1.4 修改CMakeLists.txt文件 2 手机连接电脑并编译软件2.1 编译软件2.2 更新配置及布局2.3 编译2.4 连接手机 3 自己数据集训练模型的部署4 参考 1 准备Android项目文件 1.1…