Newcoder 143 H.subseq(BIT)
阿新 • • 發佈:2018-12-10
Description
給出一個長度為的序列,定義序列是好的當且僅當以下條件成立:
1.
2.
3.
求所有好的序列中字典序第小的
Input
第一行輸入兩個整數,之後輸入個整數
Output
輸出字典序第小的好的序列,無解則輸出
Sample Input
3 2 1 2 3
Sample Output
2 1 2
Solution
以表示以開頭的滿足條件的序列個數,那麼有,用樹狀陣列維護的值,從後往前轉移,每次把根據的值插入樹狀陣列中,即可得到序列
之後從前往後考慮字典序第小的序列,假設第一位放,那麼有種方案數,若,說明第一位確實是,進而考慮第二位的取值(注意:1.每次考慮當前位的取值必然要大於已經確定的前一位取值;2.由於確定完當前位後,後面的取值有空和非空兩種情況,此時要將減一來去掉後面為空的情況,減完後若為說明後面確實為空,否則繼續考慮後面位的取值),若,說明第一位不是,那麼,表示有種字典序小的方案已經考慮了,下面考慮其他值放在第一位,以此類推,若考慮完所有元素仍然非則無解,否則已經確定的序列即為答案,時間複雜度
Code
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
ll INF=2e18;
#define maxn 500005
struct BIT
{
#define lowbit(x) (x&(-x))
ll b[maxn],n;
void init(int _n)
{
n=_n;
for(int i=1;i<=n;i++)b[i]=0;
}
void update(int x,ll v)
{
while(x<=n)
{
b[x]+=v;
b[x]=min(b[x],INF);
x+=lowbit(x);
}
}
ll query(int x)
{
ll ans=0;
while(x)
{
ans+=b[x];
ans=min(ans,INF);
x-=lowbit(x);
}
return ans;
}
}bit;
int n,a[maxn],h[maxn];
ll k,dp[maxn];
vector<int>ans;
int main()
{
scanf("%d%lld",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
h[i-1]=a[i];
}
sort(h,h+n);
int m=unique(h,h+n)-h;
bit.init(m);
for(int i=n;i>=1;i--)
{
a[i]=m+1-(lower_bound(h,h+m,a[i])-h+1);
dp[i]=bit.query(a[i]-1)+1;
dp[i]=min(dp[i],INF);
bit.update(a[i],dp[i]);
}
for(int i=1;i<=n;i++)
{
if(ans.size()>0&&a[i]>=a[ans[ans.size()-1]])continue;
if(k==0)break;
if(dp[i]>=k)
{
ans.push_back(i);
k--;
}
else k-=dp[i];
}
if(k)printf("-1\n");
else
{
printf("%d\n",ans.size());
for(int i=0;i<ans.size();i++)
printf("%d%c",ans[i],i==ans.size()-1?'\n':' ');
}
return 0;
}