当前位置: 首页 > news >正文

BZOJ5289 洛谷4437:[HNOI/AHOI2018]排列——题解

https://www.lydsy.com/JudgeOnline/problem.php?id=5289

https://www.luogu.org/problemnew/show/P4437

考虑对于a[i]=m,a[m]=n,我们令p[j]=i,p[k]=m(一定会有一对(j,k)满足这个条件的),则我们会有p[k]=a[p[j]],此时我们要满足k<j,也就是a[m]放的位置要比a[i]靠前。

也就是说选第m个之后才能选第i个。

转换成图论模型就是m->i <=> a[i]->i。

那么问题豁然开朗,首先如果图中有环就能判断无解了。

如果有解则必然为以0为根的有向树,则答案为每个节点i被拿到的时间*w[i](前提是i的父亲被拿才可以拿i)。

再考虑最大化答案,则我们让树中最小值min尽可能早的被拿到就好了。

继续贪心,则如果当前局面能够拿到min则一定拿min,换句话将就是拿了min的父亲就一定拿min。

那么父亲和min之间就成了捆绑关系,于是将其缩起来,在缩的过程中更新答案,然后递归这个过程就好了。

每次找min可以用堆维护,复杂度O(nlogn)。

(PS:更新答案,每次更新显然是这个点前面一些点被选了,于是它一定产生了前面这些点个数*w[该点]的价值)

那么就需要考虑我们缩完的点的w要怎么计算,对于两个集合a,b要合并,显然用在计算上的w=wa+wb,但是用堆排序的时候就不能这么做了。

自然能想到取平均值,虽然我不会证明,不过考量一下发现差不多。

#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
typedef long long ll;
typedef long double dl;
typedef pair<dl,int>pii;
#define fi first
#define se second
typedef __gnu_pbds::priority_queue<pii,greater<pii>,__gnu_pbds::pairing_heap_tag> heap;
const int N=5e5+5;
inline int read(){
    int X=0,w=0;char ch=0;
    while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
struct node{
    int to,nxt;
}e[N];
int n,cnt,head[N],vis[N],a[N],num,fa[N],size[N];
ll w[N],ans;
heap::point_iterator id[N];
heap q;
inline void add(int u,int v){
    e[++cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt;
}
bool dfs(int u){
    vis[u]=1;num++;
    for(int i=head[u];i;i=e[i].nxt){
    int v=e[i].to;
    if(vis[v]||!dfs(v))return 0;
    }
    if(!u&&num<=n)return 0;
    return 1;
}
inline int find(int x){
    if(x==fa[x])return x;
    return fa[x]=find(fa[x]);
}
int main(){
    n=read();
    for(int i=1;i<=n;i++)a[i]=read(),add(a[i],i);
    for(int i=1;i<=n;i++)w[i]=read();
    if(!dfs(0)){puts("-1");return 0;}
    for(int i=0;i<=n;i++)fa[i]=i,size[i]=1;
    for(int i=1;i<=n;i++)id[i]=q.push(pii(w[i],i));
    while(!q.empty()){
    int u=q.top().se,v=a[u];q.pop();
    int rt=find(v);
    ans+=w[u]*size[rt];
    fa[u]=rt;w[rt]+=w[u];size[rt]+=size[u];
    if(rt)q.modify(id[rt],pii((dl)w[rt]/size[rt],rt));
    }
    printf("%lld\n",ans);
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

 +本文作者:luyouqi233。               +

 +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

转载于:https://www.cnblogs.com/luyouqi233/p/9112242.html

相关文章:

  • mysql grant授权
  • classloader实战:一个程序使用相同数据库的两个不同版本的jar包
  • 卷积核与特征提取
  • 常用的几个vagrant命令
  • SQL优化笔记
  • 【总结整理】关于二手交易平台的讨论
  • jdk1.8 HashMap源码分析(resize函数)
  • (转)使用VMware vSphere标准交换机设置网络连接
  • 阿里云服务反射攻击,解决办法
  • MySQL运维进阶-MySQL双主(master-master)+半同步(Semisync Repl
  • 细说setTimeout/setImmediate/process.nextTick的区别
  • ORA-28040: No matching authentication protocol
  • chmod-chown-umask-lsattr-chattr
  • java实现图片转ascii字符画
  • [CF494C]Helping People
  • JavaScript-如何实现克隆(clone)函数
  • 2017届校招提前批面试回顾
  • Java编程基础24——递归练习
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • Linux链接文件
  • python3 使用 asyncio 代替线程
  • React 快速上手 - 06 容器组件、展示组件、操作组件
  • Spring Cloud Feign的两种使用姿势
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • v-if和v-for连用出现的问题
  • Vue.js源码(2):初探List Rendering
  • - 概述 - 《设计模式(极简c++版)》
  • 技术胖1-4季视频复习— (看视频笔记)
  • 两列自适应布局方案整理
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 如何用vue打造一个移动端音乐播放器
  • 三栏布局总结
  • 微信端页面使用-webkit-box和绝对定位时,元素上移的问题
  • 想写好前端,先练好内功
  • 异步
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • 【干货分享】dos命令大全
  • ​ArcGIS Pro 如何批量删除字段
  • ###C语言程序设计-----C语言学习(6)#
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (ISPRS,2023)深度语义-视觉对齐用于zero-shot遥感图像场景分类
  • (超详细)语音信号处理之特征提取
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (四)JPA - JQPL 实现增删改查
  • (万字长文)Spring的核心知识尽揽其中
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .net framework 4.0中如何 输出 form 的name属性。
  • .net 怎么循环得到数组里的值_关于js数组
  • .NET性能优化(文摘)
  • ?
  • @synthesize和@dynamic分别有什么作用?