zoukankan      html  css  js  c++  java
  • hdu5489 Removed Interval dp+线段树优化

    现在看这题居然直接秒了。。。去年看的时候还以为神题。。

    设以第i项为结尾的lis前缀为f[i],以第j项为结尾的lis后缀为g[i],如果求出f[i]和g[j],然后枚举i,快速找到最大的满足a[j]>a[i]的g[j]就可以了。注意到如果将f[i]从后往前枚举,那么只要添加g[j]而不用删除操作了,因此枚举f[i],在线段树中找(a[i]+1,Xn]中g的最大值就可以了,ans=f[i]+max(g[j]) (a[j]>a[i]且j>i+L),然后顺势把g[j]插入线段树。

    求f[i]也是dp+线段树优化,f[i]=max(f[j])+1 (a[j]<a[i])。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    #define key_val ch[ch[rt[i]][1]][0]
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=1000100;
    const int INF=1e9+10;
    
    int n,L;
    int a[maxn],X[maxn],Xn;
    int f[maxn],g[maxn];
    int Max[maxn<<2];
    
    void push_up(int rt)
    {
        Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
    }
    
    void build(int l,int r,int rt)
    {
        if(l==r){
            Max[rt]=0;
            return;
        }
        int m=(l+r)>>1;
        build(lson);build(rson);
        push_up(rt);
    }
    
    void update(int p,int c,int l,int r,int rt)
    {
        if(l==r){
            Max[rt]=max(Max[rt],c);
            return;
        }
        int m=(l+r)>>1;
        if(p<=m) update(p,c,lson);
        else update(p,c,rson);
        push_up(rt);
    }
    
    int query(int L,int R,int l,int r,int rt)
    {
        if(L>R) return 0;
        if(L<=l&&r<=R) return Max[rt];
        int m=(l+r)>>1;
        int res=0;
        if(L<=m) res=max(res,query(L,R,lson));
        if(R>m) res=max(res,query(L,R,rson));
        return res;
    }
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
        #endif
        int T;cin>>T;
        REP(casen,1,T){
            scanf("%d%d",&n,&L);
            REP(i,1,n) scanf("%d",&a[i]),X[i]=a[i];
            sort(X+1,X+n+1);
            Xn=unique(X+1,X+n+1)-(X+1);
            REP(i,1,n) a[i]=lower_bound(X+1,X+Xn+1,a[i])-X;
            build(1,Xn,1);
            f[0]=0;
            REP(i,1,n) f[i]=query(1,a[i]-1,1,Xn,1)+1,update(a[i],f[i],1,Xn,1);
            build(1,Xn,1);
            int ans=0,tmp=0;
            for(int i=n;i>=1;i--){
                int j=i-L;
                if(j>=0){
                    tmp=f[j]+query(a[j]+1,Xn,1,Xn,1);
                    ans=max(ans,tmp);
                }
                g[i]=query(a[i]+1,Xn,1,Xn,1)+1;
                update(a[i],g[i],1,Xn,1);
            }
            printf("Case #%d: %d
    ",casen,ans);
        }
        return 0;
    }
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    oracle计算记录条数
    oracle 尽量多使用COMMIT
    oracle 用TRUNCATE替代DELETE
    oracle 删除重复记录
    oracle整合简单,无关联的数据库访问
    oracle使用DECODE函数来减少处理时间
    oralce 减少访问数据库的次数
    古城钟楼微博地支报时程序铛,100行代码实现,价值一天20万粉丝
    C#中HttpWebRequest与HttpWebResponse的使用方法
    C#中用HttpWebRequest中发送GET/HTTP/HTTPS请求
  • 原文地址:https://www.cnblogs.com/--560/p/5211163.html
Copyright © 2011-2022 走看看