zoukankan      html  css  js  c++  java
  • [51nod1218]最长递增子序列 V2

    喜闻乐见的大水题。
    先离散化,求一下正的最长上升子序列,再求一下反的最长下降子序列。然后看这两个加起来等不等于|lis|+1,然后如果能做某个位置的只出现一次,它就是不可替代的。(看代码吧

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    const int N=50005;
    int t[N],n,a[N],lsh[N],cnt[N],tot,g[N],f[N];
    void add(int i,int mx){
    	for(;i<=n;i+=i&-i) t[i]=max(mx,t[i]);
    }
    int query(int i){
    	int ans=0;
    	for(;i;i-=i&-i) ans=max(ans,t[i]);
    	return ans;
    }
    int ans,u;
    int main() {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++) scanf("%d",&a[i]),lsh[i]=a[i];
    	sort(lsh+1,lsh+1+n);u=unique(lsh+1,lsh+1+n)-lsh-1;
    	for(int i=1;i<=n;i++) 
                a[i]=lower_bound(lsh+1,lsh+1+u,a[i])-lsh,
                f[i]=query(a[i])+1,add(a[i],f[i]),ans=max(ans,f[i]);
    	memset(t,0,sizeof t);
    	for(int i=n;i;i--) g[i]=query(u-a[i]+1)+1,add(u-a[i]+1,g[i]);
    	for(int i=1;i<=n;i++) if(f[i]+g[i]==ans+1) lsh[++tot]=i,cnt[f[i]]++;
    	printf("A:");
    	for(int i=1;i<=tot;i++) if(cnt[f[lsh[i]]]!=1) printf("%d ",lsh[i]);
    	printf("
    B:");
    	for(int i=1;i<=tot;i++) if(cnt[f[lsh[i]]]==1) printf("%d ",lsh[i]);
    }
    
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    使用POI操作Excel时对事先写入模板的公式强制执行
    centos7下python3和pycharm安装
    IntelliJ IDEA 快捷键终极大全
    netcore XmlDocument 使用Load和Save方法
    Add File as a Link on Visual Studio
    C#开源项目
    Shell bash和sh区别
    SecureCRT中Vim颜色
    查找局域网中未知设备的IP
    代码分支管理
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9642537.html
Copyright © 2011-2022 走看看