• zoj 2319 Beautiful People 夜


    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1319

    这题给人的第一感觉就是最长上升子序列,按S排序,对B进行求解最长上升子序列,但是N太大

    o(n^2)肯定不行,所以要用优化,我是用了线段数进行优化。

    不是经常用类,这次用了一下,还是有很多小问题的,如果在函数内部静态申请一个局部变量对象

    由于对象内有很大的数组,这样就相当于在函数所占用的栈区内申请了很大数组,没有语法错误,但c++是不允许它执行的

    换成从堆区申请就好了,不过要记得delete否则会超内存

    DP思想+线段树优化

    代码:

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<set>
    #include<map>
    #include<algorithm>
    
    #define LL long long
    
    using namespace std;
    
    const int N=100005;
    struct node
    {
        int x,y;
        int index;
    }man[N];
    map<int,int>mt;
    stack<int>st;
    int Max[N],f[N];
    class segTree
    {
        public:
        segTree(int s,int e)
        {
            build(s,e);
        }
        private:
        struct node
        {
            int l,r,k;
        }tree[N*4];
        public:
        void build(int l,int r,int x=1)
        {
            tree[x].l=l;
            tree[x].r=r;
            tree[x].k=0;
            if(l==r)
            return ;
            int mid=(l+r)>>1;
            build(l,mid,(x<<1));
            build(mid+1,r,((x<<1)|1));
        }
        void insert(int p,int k,int x=1)
        {
            if(Max[tree[x].k]<Max[k])
            tree[x].k=k;
            if(tree[x].l==tree[x].r)
            return ;
            if(p<=((tree[x].l+tree[x].r)>>1))
            insert(p,k,(x<<1));
            else
            insert(p,k,((x<<1)|1));
        }
        int getMax(int l,int r,int x=1)
        {
            if(tree[x].l==l&&tree[x].r==r)
            return tree[x].k;
            int mid=(tree[x].l+tree[x].r)>>1;
            if(r<=mid)
            return getMax(l,r,(x<<1));
            else if(l>mid)
            return getMax(l,r,((x<<1)|1));
            else
            {
                int k1=getMax(l,mid,(x<<1));
                int k2=getMax(mid+1,r,((x<<1)|1));
                return (Max[k1]>Max[k2])?k1:k2;
            }
        }
    };
    bool cmpx(node a,node b)
    {
        if(a.x==b.x)
        return a.y<b.y;
        return a.x<b.x;
    }
    bool cmpy(node a,node b)
    {
        if(a.y==b.y)
        return a.x<b.x;
        return a.y<b.y;
    }
    int main()
    {
        //freopen("data.in","r",stdin);
        int T;
        cin>>T;
        while(T--)
        {
            int n;
            cin>>n;
            for(int i=1;i<=n;++i)
            {
                cin>>man[i].x>>man[i].y;
                man[i].index=i;
            }
            sort(man+1,man+n+1,cmpy);
            mt.clear();
            int I=0;
            for(int i=1;i<=n;++i)
            if(i==1||man[i].y!=man[i-1].y)
            mt[man[i].y]=(++I);
            sort(man+1,man+n+1,cmpx);
            memset(Max,0,sizeof(Max));
            memset(f,-1,sizeof(f));
            segTree *myTree = new segTree(0,I);
            int s=0;
            for(int i=1;i<=n;++i)
            {
                int l=mt[man[i].y];
                int k=myTree->getMax(0,l-1);
                Max[i]=Max[k]+1;
                f[i]=k;
                if(Max[i]>Max[s])
                s=i;
                st.push(i);
                if(i==n||man[i].x!=man[i+1].x)
                {
                    while(!st.empty())
                    {
                        int tmp=st.top();st.pop();
                        myTree->insert(mt[man[tmp].y],tmp);
                    }
                }
            }
            delete myTree;
            cout<<Max[s]<<endl;
            while(f[s]!=0)
            {
                cout<<man[s].index<<" ";
                s=f[s];
            }
            cout<<man[s].index<<endl;
            if(T>0)
            cout<<endl;
        }
        return 0;
    }
    

      

  • 相关阅读:
    前端三剑客:html,css,JavaScript
    Python的开发之路
    python-win32操作excel的一些特殊功能
    pillow处理图片横向与纵向的合并
    部署django+uwsgi+Virtualenv+nginx+supervisor详细步骤
    python实现下载文件路径自动添加(1)的递增路径
    cx_Oracle连接oracle数据库
    pillow模块常用方法
    python内建集合模块collections功能,计数,有序,双向队列
    paramiko批量上传下载sftp,解决访问windows系列sftp乱码问题
  • 原文地址:https://www.cnblogs.com/liulangye/p/3055800.html
Copyright © 2020-2023  润新知