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

P5967 [POI 2016] Korale 题解

P5967 [POI 2016] Korale

题目描述

nnn 个带标号的珠子,第 iii 个珠子的价值为 aia_iai

现在你可以选择若干个珠子组成项链(也可以一个都不选),项链的价值为所有珠子的价值和。

给出所有可能的项链排序,先按权值从小到大排序,对于权值相同的,根据所用珠子集合的标号的字典序从小到大排序。

请输出第 kkk 小的项链的价值,以及所用的珠子集合。

输入格式

第一行包含两个正整数 n,kn,kn,k
第二行包含 nnn 个正整数,依次表示每个珠子的价值 aia_iai

输出格式

第一行输出第 kkk 小的项链的价值。
第二行按标号从小到大依次输出该项链里每个珠子的标号。

输入输出样例 #1

输入 #1

4 10
3 7 4 3

输出 #1

10
1 3 4

说明/提示

对于 100%100\%100% 的数据,1≤n≤1061\le n\le 10^61n1061≤k≤min⁡(2n,106)1\le k\le \min(2^n,10^6)1kmin(2n,106)1≤ai≤1091\le a_i\le 10^91ai109

思路

类似P2048超级钢琴~

把两问分开做。

第一问。先将数从小到大排序。然后维护一个优先队列,队列元素为 (w,i)(w,i)(w,i) 表示此时价值为 www ,并且选到了第 iii 个,队列中按价值排序。每次我们取出一个最小价值,出队同时判断答案,然后再加入 (w+ai+1,i+1)(w+a_{i+1},i+1)(w+ai+1,i+1) 表示选择 i+1i+1i+1 ,加入(w+ai+1−ai,i+1)(w+a_{i+1}-a_i,i+1)(w+ai+1ai,i+1) ,表示反悔这一步的操作。

第二问。可以根据第一问的答案来暴搜。也就是要找答案为 ansansans,小于等于ansansans 的数有 kkk 个的方案。从前往后搜来保证字典序最小。直接 O(n)O(n)O(n) 找可行状态复杂度爆炸,我们用线段树记录最小值。每次线段树上二分确定位置(每次找字典序最小且符合条件的点)。每次二分是 O(logn)O(\text log n)O(logn) ,至多进行 O(k)O(k)O(k) 次,所以复杂度是O(klogn)O(klogn)O(klogn)

code:


```cpp
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e6+15;
ll n,k;
ll a[N],b[N],ans2[N];	
ll lst=0,cnt=0,nw=0;
struct tree{int l,r;ll w,mn;
}tr[N<<2]; 
struct node{ll w,len;bool operator < (const node &p) const{return w>p.w;}
};
priority_queue<node> q;
ll read(){ll x=0;char c=getchar();while(c<'0'||c>'9'){c=getchar();}while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}return x;
}
void build(int p,int l,int r){tr[p].l=l,tr[p].r=r;if(l==r){tr[p].mn=a[l];return ;}int mid=(l+r)>>1;build(p<<1,l,mid);build(p<<1|1,mid+1,r);tr[p].mn=min(tr[p<<1].mn,tr[p<<1|1].mn);
}
int query(int p,int l,int r,int k,ll x){if(k<=l){if(tr[p].mn>x) return 0;if(l==r) return l;}int mid=(l+r)>>1;if(k<=mid){int y=query(p<<1,l,mid,k,x);if(y) return y;}//else{return query(p<<1|1,mid+1,r,k,x);
//	}
}
void dfs(int nwi,ll as){
//	cout<<nw<<" "<<as<<" "<<cnt<<endl;if(as==0){cnt--;if(cnt!=0) return ;for(int i=1;i<=nw;++i){printf("%lld ",ans2[i]);}printf("\n");return ;}if(cnt<0) return ;for(int i=nwi+1;i<=n;++i){i=query(1,1,n,i,as);//i右侧第一个<as if(i==0) return ;ans2[++nw]=i;dfs(i,as-a[i]);nw--;}
}
int main(){//freopen("pearl.in","r",stdin);//freopen("pearl.out","w",stdout);scanf("%lld%lld",&n,&k);k--;for(int i=1;i<=n;++i){a[i]=read();b[i]=a[i];}sort(b+1,b+1+n);build(1,1,n);node xx;xx.w=b[1],xx.len=1;q.push(xx);cnt=0;for(int i=1;i<=k;++i){node x=q.top();q.pop();if(x.w==lst) cnt++;else lst=x.w,cnt=1;x.len++;if(x.len>n) continue;x.w+=b[x.len];q.push(x);x.w-=b[x.len-1];q.push(x);}
//	cout<<cnt<<endl;printf("%lld\n",lst);dfs(0,lst);return 0;
} 
http://www.dtcms.com/a/331073.html

相关文章:

  • Transformer之多头注意力机制和位置编码(二)
  • Canon PowerShot D30相机 CHDK 固件 V1.4.1
  • 5.Ansible-playbook-模块介绍(知识点补充)
  • 【Postgresql】实现 PostgreSQL 全量审计日志:记录所有 SQL 操作及来源
  • 【C++】细说继承(2w字详解)
  • ROS机器人云实践案例博客建议和范文-AI版本
  • imx6ull-驱动开发篇24——Linux 中断API函数
  • MATLAB绘制各种心形曲线
  • window显示驱动开发—在混合系统中使用跨适配器资源
  • nginx-集成prometheus监控(k8s)
  • GitHub 热榜项目 - 日榜(2025-08-14)
  • 一、linux内存管理学习(1):物理内存探测
  • 京东商品列表API开发指南
  • OpenCV对椒盐处理后的视频进行均值滤波处理
  • Opencv 边界填充 图像运算 阈值处理 和图像平滑处理
  • 文件上传接口接收不到文件入参
  • 题解:P4777 【模板】扩展中国剩余定理(EXCRT)
  • Qt项目查找依赖库打包
  • IDEA、Pycharm、DataGrip等激活破解冲突问题解决方案之一
  • Springboot项目重启后Session依旧存在
  • Python包性能优化与并发编程:构建高性能应用的核心技术(续)
  • 轻量级开源全文搜索引擎:Manticore Search 入门介绍
  • C++基础(①入门教程)
  • 本地jar导入到本地仓科和远程仓库
  • Maven学习笔记
  • 92、23种设计模式-单例模式
  • 项目日志框架与jar中日志框架冲突 解决
  • 《多级缓存架构设计与实现全解析》
  • 自动化测试|持续集成Git使用详解
  • label studio 服务器端打开+xshell端口转发设置