AcWing 1010. 拦截导弹(1e5数据,双重二分优化)(O(nlogn))
原题链接
简单
作者:
記得
,
2021-04-06 21:40:02
,
所有人可见
,
阅读 1105
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int tfind1(int l, int r, int x);//求最长上升子序列
int tfind2(int l, int r, int x);//找到第一个小于x的数
int n=1;
int a[N];
int f[N], g[N];
signed main()
{
while(cin>>a[n]) n++;
n--;
int len=0;
for(int i=1;i<=n;i++)
{
int k=tfind1(0, len, a[i]);
f[k+1]=a[i];
len=max(len, k+1);
}
int cnt=0;
for(int i=1;i<=n;i++)
{
int k=tfind2(0, cnt+1, a[i]);//由于下标从1,开始,cnt要加1
g[k+1]=a[i];
if(k>cnt) cnt++;
}
cout<<len<<endl<<cnt<<endl;
}
int tfind1(int l, int r, int x)
{
while(l<r)
{
int mid=l+r+1>>1;
f[mid]>=x?l=mid:r=mid-1;
}//大于等于
return l;
}
int tfind2(int l, int r, int x)
{
while(l<r)
{
int mid=l+r+1>>1;
g[mid]<x?l=mid:r=mid-1;
}
return l;
}
谢谢
没事%%%
%%%