热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

[COCI20112012#4]OGRADA题解

看到有大小关系限制,考虑拓扑排序,并在拓扑的同时从大到小进行填数。问题转换为,对于拓扑队列中的所有元素(即\(B\)的位置),应该把最大的数填在哪个位置上。然后快快乐乐分类讨论就

看到有大小关系限制,考虑拓扑排序,并在拓扑的同时从大到小进行填数。

问题转换为,对于拓扑队列中的所有元素(即 \(B'\) 的位置),应该把最大的数填在哪个位置上。

然后快快乐乐分类讨论就行了。

约定: 蓝色块为已填,灰色块为可填(在拓扑队列中),白色块为不能填(不在拓扑队列中),优先级越小越先填。



  • \(A_{i-1}>A_i

    此时 \(B'_i\) 的值越小越好,并且 \(B'_i\) 的值每减小 \(1\),答案增加 \(2\),优先级为 \(4\)



  • \(A_{i-1}>A_i>A_{i+1}:\)

    此时从 \(B'_{i-1}\)\(B'_{i+1}\) 对答案的贡献为 \(B'_{i-1}-B'_{i+1}\),与 \(B'_{i}\) 无关,优先级为 \(2\)



  • \(A_{i-1}\(A_{i-1}>A_i>A_{i+1}\) 同理。



  • \(A_{i-1}A_{i+1}:\)

    此时 \(B'_i\) 的值越大越好,并且 \(B'_i\) 的值每增加 \(1\),答案增加 \(2\),优先级为 \(0\)



  • \(i=1,A_i>A_{i+1}:\)

    此时 \(B'_i\) 的值越大越好,并且 \(B'_i\) 的值每增加 \(1\),答案增加 \(1\),优先级为 \(1\)



  • \(i=1,A_i

    此时 \(B'_i\) 的值越小越好,并且 \(B'_i\) 的值每减小 \(1\),答案增加 \(1\),优先级为 \(3\)



  • \(i=n\)\(i=1\) 同理。



拓扑的时候用优先队列,按照优先级排序即可。

(其实这玩意儿写出来更像 \(\text{Dijstra}\) /qd)


代码

分类讨论很麻烦,但代码不复杂。

#include
#define ll long long
using namespace std;
const int maxn=300010;
inline int read(){
int x=0;
char c=getchar();
for(;!(c>='0'&&c<='9');c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+c-'0';
return x;
}
struct edge{
int v,to;
}e[maxn<<1];
int head[maxn],ecnt;
void addedge(int u,int v){
e[++ecnt].v=v,e[ecnt].to=head[u],head[u]=ecnt;
}
priority_queue

,vector

>,greater

> >q;
bitsetvis;
int ru[maxn],n;
int a[maxn],b[maxn];
int Ans[maxn];
int Num(int i){
//返回对应位置优先级
if(i-1&&i if(!Ans[i-1]&&!Ans[i+1]) return 0;
if(Ans[i-1]&&Ans[i+1]) return 4;
return 2;
}
if(i-1){
if(Ans[i-1]) return 3;
return 1;
}
if(Ans[i+1]) return 3;
return 1;
}
void Solve(){
for(int i=1;i<=n;i++)
if(!ru[i]) q.push(make_pair(Num(i),i));
pairt;
int cnt=0;
//拓扑排序写法参考Dijstra堆优化版本
while(!q.empty()){
t=q.top(),q.pop();
if(vis[t.second]) continue;
//填过,continue
if(Num(t.second)^t.first) continue;
//不是当前状态(不是最新版本),continue
Ans[t.second]=b[++cnt],vis[t.second]=1;
if(t.second-1&&!ru[t.second-1])
q.push(make_pair(Num(t.second-1),t.second-1));
if(t.second q.push(make_pair(Num(t.second+1),t.second+1));
for(int i=head[t.second];i;i=e[i].to){
ru[e[i].v]--;
if(!ru[e[i].v])
q.push(make_pair(Num(e[i].v),e[i].v));
}
}

}
int main(){
n=read();
for(int i=1;i<=n;i++)
a[i]=read();
for(int i=1;i<=n;i++)
b[i]=read();
sort(b+1,b+1+n,greater());
for(int i=1;i if(a[i]>a[i+1])
addedge(i,i+1),ru[i+1]++;
else addedge(i+1,i),ru[i]++;
Solve();
ll ans=0;
for(int i=1;i ans+=abs(Ans[i]-Ans[i+1]);
printf("%lld\n",ans);
for(int i=1;i<=n;i++)
printf("%d ",Ans[i]);
return 0;
}


推荐阅读
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • Linux的uucico命令使用方法及工作模式介绍
    本文介绍了Linux的uucico命令的使用方法和工作模式,包括主动模式和附属模式。uucico是用来处理uucp或uux送到队列的文件传输工具,具有操作简单快捷、实用性强的特点。文章还介绍了uucico命令的参数及其说明,包括-c或--quiet、-C或--ifwork、-D或--nodetach、-e或--loop、-f或--force、-i或--stdin、-I--config、-l或--prompt等。通过本文的学习,读者可以更好地掌握Linux的uucico命令的使用方法。 ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 栈和队列的共同处和不同处
    本文主要介绍了栈和队列的共同处和不同处。栈和队列都是由几个数据特性相同的元素组成的有限序列,也就是线性表。队列是限定仅在表的一端插入元素、在另一端删除元素的线性表,遵循先进先出的原则。栈是限定仅在表尾进行插入或删除操作的线性表,遵循后进先出的原则。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 本文介绍了栈和队列的区别及其特点。栈是一种先进后出的线性表,只能在表的一端进行插入和删除操作;队列是一种先进先出的线性表,只能在表的一端进行插入和在另一端进行删除操作。栈和队列是两种广泛使用的线性数据结构,它们的基本操作具有特殊性。栈的遍历需要遍历整个栈才能取出数据,并需要为数据开辟临时空间,而队列基于地址指针进行遍历,可以从头或尾部开始遍历,但不能同时遍历,且无需开辟临时空间。栈和队列在程序设计中具有重要应用。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 一、什么是闭包?有什么作用什么是闭包闭包是定义在一个函数内部的函数,它可以访问父级函数的内部变量。当一个闭包被创建时,会关联一个作用域—— ... [详细]
  • 本文讨论了读书的目的以及学习算法的重要性,并介绍了两个算法:除法速算和约瑟夫环的数学算法。同时,通过具体的例子和推理,解释了为什么x=x+k序列中的第一个人的位置为k,以及序列2和序列3的关系。通过学习算法,可以提高思维能力和解决问题的能力。 ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
author-avatar
陈怡伶翰纬
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有