列表

详情


NC200200. 快乐风男

描述

 特别喜欢玩快乐风男,并且他喜欢无缝E的感觉。

现在  面前有n个兵,呈线性排列编号为 ,每个小兵携带  个金币。为了体现快乐的极致,  知道了每个小兵携带的金币,快乐的他E往无前(也就是说他不会回头),但是快乐的他每次E的小兵的金币都严格递增,为了  E到更多的小兵,请你给出他E兵的编号。如果有多个快乐方案,给出字典序最小的方案

输入描述

第一行一个整数 ,表示小兵的个数。

接下来一行  个整数,表示编号为i的小兵所携带的金币数量。

输出描述

第一行输出一个整数 ,表示  最多能E到小兵的个数。

接下来一行输出  个整数,表示  能E到的小兵的下标。行末不要加空格。

示例1

输入:

5
1 2 4 3 5

输出:

4
1 2 3 5

说明:

 有两种E到4个小兵的方案,1 2 3 5 和 1 2 4 5,其中下标1 2 3 5的字典序小于1 2 4 5,所以答案是1 2 3 5

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 23ms, 内存消耗: 2272K, 提交时间: 2019-12-21 21:33:09

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2e5+10;
#define fi first
#define se second
#define pb push_back
int n,a[N];
int t[N];
int add(int now){
    int b=0;
    for(;now<N;now+=now&-now)b=max(t[now],b);
    return b;
}
int get(int x,int b){
    for(;x;x-=x&-x)t[x]=max(b,t[x]);
}
int f[N];
int main() {
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    int G=0;
    for(int i=n;i>=1;i--){
        f[i]=add(a[i]+1)+1;
        get(a[i],f[i]);
        G=max(G,f[i]);
    }
    cout<<G<<endl;
    for(int i=1;i<=n;i++){
        if(f[i]==G)cout<<i<<' ',G--;
    }
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 21ms, 内存消耗: 2148K, 提交时间: 2020-02-29 17:22:39

#include<bits/stdc++.h>
using namespace std;

int t=0,V[100005],S[100005],a[100005];
int main()
{
    int i,j,n,l,r,m;
	scanf("%d",&n);
	for(i=1;i<=n;i++)scanf("%d",&a[i]);
	for(S[0]=1e9,i=n;i;i--)
	{
		if(a[i]<S[t])S[++t]=a[i],V[i]=t;
		else 
		{
			for(l=1,r=t;l<=r;)
			{
				m=(l+r)>>1;
				if(S[m]<=a[i])j=m,r=m-1;
				else l=m+1;
			}
			V[i]=j,S[j]=a[i];
		}
	}
	printf("%d\n",t);
    for(i=1;i<=n;i++)if(V[i]==t)printf("%d ",i),t--;
    return 0;
}

上一题