第一个和最后一个数是必须要标记的 这就是一个突破口 然后找区间[2,n-1]的最小值是否小于第一与最后一个数的最小值 若小于的话则该数必须要标记 然后从该数的位置将区间一分为二 否则查最大值是否大于第一与最后一个数的最大值
这样走的每一步都是基于当前情况的必然选择 且是唯一正确选择
#include <bits/stdc++.h>
using namespace std;
#define N 0x3f3f3f3f
struct node1
{
int l;
int r;
int val[2];
int id[2];
};
struct node2
{
int l;
int r;
};
node1 tree[400010];
queue <node2> que;
node2 num[100010];
int book[100010];
int n;
void pushup(int cur)
{
if(tree[2*cur].val[0]<tree[2*cur+1].val[0])
{
tree[cur].val[0]=tree[2*cur].val[0];
tree[cur].id[0]=tree[2*cur].id[0];
}
else
{
tree[cur].val[0]=tree[2*cur+1].val[0];
tree[cur].id[0]=tree[2*cur+1].id[0];
}
if(tree[2*cur].val[1]>tree[2*cur+1].val[1])
{
tree[cur].val[1]=tree[2*cur].val[1];
tree[cur].id[1]=tree[2*cur].id[1];
}
else
{
tree[cur].val[1]=tree[2*cur+1].val[1];
tree[cur].id[1]=tree[2*cur+1].id[1];
}
}
void build(int l,int r,int cur)
{
int m;
tree[cur].l=l;
tree[cur].r=r;
if(l==r)
{
tree[cur].val[0]=num[l].l;
tree[cur].val[1]=num[l].l;
tree[cur].id[0]=num[l].r;
tree[cur].id[1]=num[l].r;
return;
}
m=(l+r)/2;
build(l,m,2*cur);
build(m+1,r,2*cur+1);
pushup(cur);
return;
}
node2 query(int tp,int pl,int pr,int cur)
{
node2 res1,res2;
if(pl<=tree[cur].l&&tree[cur].r<=pr)
{
res1.l=tree[cur].val[tp];
res1.r=tree[cur].id[tp];
return res1;
}
if(tp==0)
{
res1.l=N,res1.r=0;
res2.l=N,res2.r=0;
if(pl<=tree[2*cur].r) res1=query(tp,pl,pr,2*cur);
if(pr>=tree[2*cur+1].l) res2=query(tp,pl,pr,2*cur+1);
if(res1.l<res2.l) return res1;
else return res2;
}
else
{
res1.l=-N,res1.r=0;
res2.l=-N,res2.r=0;
if(pl<=tree[2*cur].r) res1=query(tp,pl,pr,2*cur);
if(pr>=tree[2*cur+1].l) res2=query(tp,pl,pr,2*cur+1);
if(res1.l>res2.l) return res1;
else return res2;
}
}
void solve()
{
node2 cur,tem,res;
while(!que.empty()) que.pop();
memset(book,0,sizeof(book));
tem.l=1,tem.r=n;
que.push(tem);
book[1]=1,book[n]=1;
while(!que.empty())
{
cur=que.front();
que.pop();
if(!(cur.l+1<=cur.r-1)) continue;
res=query(0,cur.l+1,cur.r-1,1);
if(res.l<min(num[cur.l].l,num[cur.r].l))
{
tem.l=cur.l,tem.r=res.r;
que.push(tem);
tem.l=res.r,tem.r=cur.r;
que.push(tem);
book[res.r]=1;
}
else
{
res=query(1,cur.l+1,cur.r-1,1);
if(res.l>max(num[cur.l].l,num[cur.r].l))
{
tem.l=cur.l,tem.r=res.r;
que.push(tem);
tem.l=res.r,tem.r=cur.r;
que.push(tem);
book[res.r]=1;
}
}
/*
if(min(num[cur.l].l,num[cur.r].l)<=res.l&&res.l<=max(num[cur.l].l,num[cur.r].l))
{
res=query(1,cur.l+1,cur.r-1,1);
if(!(min(num[cur.l].l,num[cur.r].l)<=res.l&&res.l<=max(num[cur.l].l,num[cur.r].l)))
{
tem.l=cur.l,tem.r=res.r;
que.push(tem);
tem.l=res.r,tem.r=cur.r;
que.push(tem);
book[res.r]=1;
}
}
else
{
tem.l=cur.l,tem.r=res.r;
que.push(tem);
tem.l=res.r,tem.r=cur.r;
que.push(tem);
book[res.r]=1;
}
*/
}
}
int main()
{
int i,j,val,ans,cnt;
while(scanf("%d",&n)!=EOF)
{
for(i=1,j=0;i<=n;i++)
{
scanf("%d",&val);
if(j==0||num[j].l!=val)
{
j++;
num[j].l=val;
num[j].r=i;
}
}
n=j;
build(1,n,1);
solve();
ans=0;
for(i=1;i<=n;i++)
{
ans+=book[i];
}
printf("%d\n",ans);
cnt=0;
for(i=1;i<=n;i++)
{
if(book[i])
{
printf("%d",num[i].r);
cnt++;
if(cnt==ans) printf("\n");
else printf(" ");
}
}
}
return 0;
}
/*
4
1 3 4 2
*/