加塞

news/2024/9/28 17:47:27

加塞

rnk7,\(100+30+10+15=155\)

题目来源:2022 牛客 OI 赛前集训营-提高组(第三场)

T1 一般图最小匹配

说的很复杂,实际水题。就是从 \(n\) 个数中选 \(2m\) 个数,两个两个求差后,求这个差的和的最小值。

显然排序之后求差是最小的,但显然不能直接贪心,考虑 DP。

先排序,然后设 \(\mathit{dp}_{i,j}\) 表示前 \(i\) 个数选 \(j\) 的方案数,在以下两种情况中取 \(\min\)

  • 不选当前数,即 \(\mathit{dp}_{i-1,j}\)
  • 选当前数,即 \(\mathit{dp}_{i-2,j-1}+a_i-a_{i-1}\)

初始化 \(\forall\mathit{dp}_{i,j}=\infty\)\(\forall\mathit{dp}_{i,0}=0\),答案即为 \(\mathit{dp}_{n,m}\)

#include<bits/stdc++.h>
#define fw fwrite(obuf,p3-obuf,1,stdout)
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
#define putchar(x) (p3-obuf<1<<20?(*p3++=(x)):(fw,p3=obuf,*p3++=(x)))
using namespace std;char buf[1<<20],obuf[1<<20],*p1=buf,*p2=buf,*p3=obuf,str[20<<2];
int read(){int x=0;char ch=getchar();while(!isdigit(ch))ch=getchar();while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar();return x;
}
template<typename T>
void write(T x,char sf='\n'){if(x<0)putchar('-'),x=~x+1;int top=0;do str[top++]=x%10,x/=10;while(x);while(top)putchar(str[--top]+48);putchar(sf);
}
constexpr int MAXN=5005;
int n,m,a[MAXN];
long long dp[MAXN][MAXN];int main(){freopen("match.in","r",stdin);freopen("match.out","w",stdout);n=read(),m=read();for(int i=1;i<=n;++i)a[i]=read();sort(a+1,a+n+1);memset(dp,0x3f,sizeof(dp));for(int i=0;i<=n;++i)dp[i][0]=0;for(int i=2;i<=n;++i)for(int j=1;j<=m;++j)dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+a[i]-a[i-1]);write(dp[n][m]);return fw,0;
}

T2 重定向

不难,没搞出来可惜了。

首先,50pts 的 \(O(Tn^2\log n)\) 暴力是好想的,暴力枚举要删除的位置,用 set 维护当前最小能填的数,在最终的序列中取字典序最小的即可。可以用 vector 自带重载小于运算符,直接比较字典序。实际上这个复杂度过不了,不知是否是出题人有意放过,但让我丢了 20pts。

考虑正解。发现复杂度瓶颈主要在求出最优的删除位置,那么我们就调用我们智慧的人类大脑得:

  • \(a_i\ne0\land a_{i+1}\ne0\),那么将 \(i\) 删除最优当且仅当 \(a_i>a_{i+1}\)
  • \(a_i\ne0\land a_{i+1}=0\),那么将 \(i\) 删除最优当且仅当 \(a_i>w\),其中 \(w\) 是当前序列能填的最小数;
  • \(a_i=0\),则只有位置 \(i\) 的后缀最小值小于当前序列能填的最小数时,删除这个后缀最小值第一次出现的位置最优。换句话说,如果后面出现了一个更小的,把这个更小的数放到前面是更优的。

如果没找到,默认删除 \(n\) 即可。注意删除的这个点的值在最后是可以回填进序列中的。找到了最优删除位置,填数就很简单。复杂度 \(O(Tn\log n)\),2s 时限加上出题人的有意防水,能过。

#include<bits/stdc++.h>
#define fw fwrite(obuf,p3-obuf,1,stdout)
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
#define putchar(x) (p3-obuf<1<<20?(*p3++=(x)):(fw,p3=obuf,*p3++=(x)))
#define INF 0x3f3f3f3f
using namespace std;char buf[1<<20],obuf[1<<20],*p1=buf,*p2=buf,*p3=obuf,str[20<<2];
int read(){int x=0;char ch=getchar();while(!isdigit(ch))ch=getchar();while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar();return x;
}
template<typename T>
void write(T x,char sf='\n'){if(x<0)putchar('-'),x=~x+1;int top=0;do str[top++]=x%10,x/=10;while(x);while(top)putchar(str[--top]+48);putchar(sf);
}
constexpr int MAXN=2e5+5;
int T,n,a[MAXN],tmp[MAXN];
int minn[MAXN],pos[MAXN];int main(){freopen("repeat.in","r",stdin);freopen("repeat.out","w",stdout);T=read();while(T--){set<int>st;n=read();for(int i=1;i<=n;++i)pos[i]=0;for(int i=1;i<=n;++i)pos[a[i]=read()]=i;for(int i=1;i<=n;++i)if(!pos[i])st.emplace(i);minn[n+1]=INF;for(int i=n;i;--i)minn[i]=min(minn[i+1],a[i]?a[i]:INF);int del=n;for(int i=1;i<n;++i)if(a[i]&&a[i+1]&&a[i]>a[i+1]){del=i;st.emplace(a[i]);break;}else if(a[i]&&!a[i+1]&&a[i]>*st.begin()){del=i;st.emplace(a[i]);break;}else if(!a[i]){if(minn[i]<*st.begin()){a[i]=minn[i],del=pos[a[i]];break;}a[i]=*st.begin(),st.erase(a[i]);}for(int i=1;i<=n;++i){if(a[i]||del==i)continue;a[i]=*st.begin(),st.erase(a[i]);}for(int i=1;i<=n;++i)if(del^i)write(a[i],' ');putchar('\n');}return fw,0;
}

T3 斯坦纳树

需要用到虚树的思想,不过输出全 1 就有 10pts。

我们首先考虑什么情况下牛的做法会假,实际上就是这种情况:

正确的斯坦纳树边权和是 \(3\),但牛的做法边权和是 \(4\)

进而我们想到,用询问的点集作为关键点构造虚树,那么一旦虚点(图中是 \(\boldsymbol2\))的度数 \(\boldsymbol{\ge3}\) 时,牛的做法一定会假。

否则,当虚点度数 \(<3\) 时,只有两种情况:

  • 若度数为 \(1\),直接删除虚点,此时必不会影响答案;
  • 若度数为 \(2\),将虚点的两端连起来即可。

但是,这样我们少考虑了一种情况:如果边权是 \(0\),那么即使边被多跑了,答案不会受到影响。

所以我们需要用并查集维护连通块,把边权为 \(0\) 的两端合并,连通块被删除当且仅当它里面的所有点被删除。至于维护,我们从后往前删点(注意这个 trick 已经很老了),按上述策略维护虚点,如果操作后无虚点,则牛的做法为真,否则为假。

#include<bits/stdc++.h>
#define fw fwrite(obuf,p3-obuf,1,stdout)
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
#define putchar(x) (p3-obuf<1<<20?(*p3++=(x)):(fw,p3=obuf,*p3++=(x)))
using namespace std;char buf[1<<20],obuf[1<<20],*p1=buf,*p2=buf,*p3=obuf,str[20<<2];
int read(){int x=0;char ch=getchar();while(!isdigit(ch))ch=getchar();while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar();return x;
}
template<typename T>
void write(T x,char sf='\n'){if(x<0)putchar('-'),x=~x+1;int top=0;do str[top++]=x%10,x/=10;while(x);while(top)putchar(str[--top]+48);if(sf^'#')putchar(sf);
}
constexpr int MAXN=3e5+5;
int n,p[MAXN],cnt[MAXN],ans[MAXN],sum;
struct Edge{int u,v,w;bool operator<(const Edge&x)const{return w<x.w;}
}e[MAXN];
int f[MAXN],siz[MAXN];
int find(int x){if(f[x]^x)f[x]=find(f[x]);return f[x];
}
unordered_set<int>st[MAXN];void del(int x){if(st[x].size()<=2&&!cnt[x]){--sum;int tmp[3],len=0;for(auto v:st[x]){tmp[++len]=v;st[v].erase(x);}st[x].clear();if(len==2){st[tmp[1]].emplace(tmp[2]);st[tmp[2]].emplace(tmp[1]);}for(int i=1;i<=len;++i)del(tmp[i]);}
}int main(){freopen("tree.in","r",stdin);freopen("tree.out","w",stdout);n=read();iota(f+1,f+n+1,1);for(int i=1,u,v,w;i<n;++i){u=read(),v=read(),w=read();e[i]={u,v,w};if(!w)f[find(u)]=find(v);}for(int i=1;i<n;++i){if(!e[i].w)continue;st[find(e[i].u)].emplace(find(e[i].v));st[find(e[i].v)].emplace(find(e[i].u));}for(int i=1;i<=n;++i)++cnt[find(p[i]=read())];for(int i=n;~i;--i){ans[i]=!sum;if(!--cnt[find(p[i])])++sum,del(find(p[i]));}for(int i=1;i<=n;++i)write(ans[i],'#');return putchar('\n'),fw,0;
}

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

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

相关文章

『模拟赛』CSP-S模拟6

『模拟赛记录』CSP-S模拟6Rank 一般 恼了怎么又狠狠挂分啊啊啊啊A. 一般图最小匹配 签。(这么多天终于签上了是吧) 结论是,跟图完全没关系。题意转换完就是从 \(n\) 个数中选出 \(m\) 对差的绝对值之和最小的数。显然我们选的每一对数都应该是这 \(n\) 个数中相邻的一组,so…

ESXi 5.5 系统克隆到SD卡或USB磁盘上

对于如何将安装在本地磁盘上的ESXi系统克隆到SD卡或USB磁盘上,以便快速实现ESXi主机的VSAN-Ready状态。正好猫猫也有点兴趣,所以,就研究了下这个方式,大致的工作思路就是“先通过dd命令将ESXi系统克隆到VMFS Datastore成为一个文件,然后再从文件弄到SD卡或USB磁盘即可”。…

昆明理工大学计算机考研专业课答题卡

--昆工昆明理工大学、计算机技术、人工智能、软件工程、网络空间安全、891计算机专业核心综合、计算机系统结构、计算机软件与理论、网络与信息安全、计算机应用技术、综合程序设计

BUUCTF(PWN)- rip

BUUCTF(PWN)- rip 打开题目得到靶机信息: node5.buuoj.cn:29045 和附件 pwn1查看文件信息为 64-bit ,用 ida 打开附件 首先 shift+f12 查找字符串,能看见 system、/bin/sh 字样,点击 please input 或者 ok,bye!!! 跳转直接进入 main 函数查看gets 并没有限制输入,gets 函…

Springboot实战——黑马点评之秒杀优化

Springboot实战——黑马点评之 秒杀优化 1 秒杀优化 先来复习以下,秒杀优惠券业务的现有实现逻辑:以上流程图中的操作串行执行,效率极低。 其中 判断秒杀库存 以及 校验一人一单 属于对数据库的读取,耗时较少;扣减库存 以及 创建订单 属于对数据库的写操作,耗时相对较久。…

PARTVI-Oracle数据库管理与开发-数据库管理员的概念

18. 数据库管理员的概念 18.1. 数据库管理员的职责 数据库管理员(DBA)的主要责任是使企业数据对其用户可用。DBA必须与开发人员紧密合作,确保他们的应用程序有效地使用数据库,并与系统管理员合作,确保物理资源充足且使用高效。Oracle DBA负责了解Oracle数据库架构以及数据…

实验作业1

实验一 任务一 源代码#include<stdio.h> int main() {printf(" o \n");printf("<H>\n");printf("I I\n");printf(" o \n");printf("<H>\n");printf("I I\n");return 0; }效果 源代码#incl…

01. 感知层环境安装

1. 软件以及驱动的安装安装ZigBee无线网络节点开发平台 IAR Embedded Workbench(简称EW) 安装串口驱动(CH340芯片)。点击安装64位的。后续就可以使用串口对开发板进行调试。 仿真器驱动程序(用来烧录代码)的安装。 安装串口工具(XCOM)。2. IAR创建工程打开安装的IAR软件,点击…