# Bzoj4345 [poi2016]korale

## 线段树+dfs寻找方案

Posted by yjjr's blog on April 8, 2018

# 题目

## Sample Input

4 10
3 7 4 3


## Sample Output

10
1 3 4


# code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
#define mem(x,num) memset(x,num,sizeof x)
#define reg(x) for(int i=last[x];i;i=e[i].next)
using namespace std;
ll f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
#define mid ((l+r)>>1)
#define lson p<<1
#define rson p<<1|1
const int maxn=1e6+6;
int n,m,cnt,top,a[maxn],num[maxn],val[maxn<<2],stk[maxn];ll ans[maxn];
struct node{ll val;int id;};
priority_queue<node> q;
inline bool operator < (node a,node b){return a.val>b.val;}
void build(int p,int l,int r){
if(l==r){val[p]=a[l];return;}
build(lson,l,mid);build(rson,mid+1,r);
val[p]=min(val[lson],val[rson]);
}
inline int query(int p,int l,int r,int Q,ll y){
if(Q<=l){
if(val[p]>y)return 0;
if(l==r)return l;
}
if(Q<=mid){
int t=query(lson,l,mid,Q,y);
if(t)return t;
}
return query(rson,mid+1,r,Q,y);
}
void dfs(int k,ll rst){
if(!cnt)return;int i;
if(!rst){
cnt--;
if(!cnt)for(i=1;i<=top;i++)printf("%d ",stk[i]);
return;
}
for(i=k+1;i<=n;i++){
i=query(1,1,n,i,rst);
if(i){
stk[++top]=i;dfs(i,rst-a[i]);top--;
}else break;
}
}
int main()
{
if(!m){puts("0");return 0;}
sort(num+1,num+1+n);
node u={num[1],1};q.push(u);
rep(i,1,m){
node now=q.top();q.pop();ans[i]=now.val;
if(i<m&&now.id<n){
now.id++;now.val+=num[now.id];q.push(now);
now.val-=num[now.id-1];q.push(now);
}
}
for(int i=m;i&&ans[i]==ans[m];i--)cnt++;
printf("%lld\n",ans[m]);
build(1,1,n);dfs(0,ans[m]);
return 0;
}