[HDU5324]Boring Class

Posted 租酥雨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[HDU5324]Boring Class相关的知识,希望对你有一定的参考价值。

vjudge

sol

字典序最小可以通过倒着\(dp\)解决。对每个\(i\)记录它可以转移到的\(dp\)值最大且字典序最小的\(nxt_i\)
尝试着写一下\(dp\)式子。
\[dp_i=max\{dp_j\}+1(j>i,L_j\le L_i,R_j\ge R_i)\]
同时要保证\(j\)最小。
\(R\)数组全部去相反数之后相当于是一个二维的最长非降子序列。
直接把所有决策往树套树里面插就行了。

code

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int gi()
{
    int x=0,w=1;char ch=getchar();
    while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if (ch=='-') w=0,ch=getchar();
    while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return w?x:-x;
}
const int N = 5e4+5;
struct segment_tree{int ls,rs,v;}t[N*150];
int n,a[N],b[N],o1[N],o2[N],len1,len2,rt[N],tot,dp[N],nxt[N],ans,start;
int better(int i,int j)
{
    if (!i) return j;
    if (dp[i]^dp[j]) return dp[i]>dp[j]?i:j;
    return i<j?i:j;
}
void modify(int &x,int l,int r,int p,int v)
{
    if (!x) x=++tot;t[x].v=better(t[x].v,v);
    if (l==r) return;int mid=l+r>>1;
    if (p<=mid) modify(t[x].ls,l,mid,p,v);
    else modify(t[x].rs,mid+1,r,p,v);
}
int query(int x,int l,int r,int ql,int qr)
{
    if (!x||l>=ql&&r<=qr) return t[x].v;
    int mid=l+r>>1;
    if (qr<=mid) return query(t[x].ls,l,mid,ql,qr);
    if (ql>mid) return query(t[x].rs,mid+1,r,ql,qr);
    return better(query(t[x].ls,l,mid,ql,qr),query(t[x].rs,mid+1,r,ql,qr));
}
int main()
{
    while (scanf("%d",&n)!=EOF)
    {
        for (int i=1;i<=tot;++i) t[i].ls=t[i].rs=t[i].v=0;
        tot=len1=len2=ans=start=0;
        for (int i=1;i<=n;++i) o1[++len1]=a[i]=gi();
        for (int i=1;i<=n;++i) o2[++len2]=b[i]=1e9-gi();
        sort(o1+1,o1+len1+1);len1=unique(o1+1,o1+len1+1)-o1-1;
        sort(o2+1,o2+len2+1);len2=unique(o2+1,o2+len2+1)-o2-1;
        for (int i=1;i<=n;++i)
        {
            a[i]=lower_bound(o1+1,o1+len1+1,a[i])-o1;
            b[i]=lower_bound(o2+1,o2+len2+1,b[i])-o2;
        }
        for (int i=n;i;--i)
        {
            int res=0;
            for (int j=a[i];j;j-=j&-j)
                res=better(res,query(rt[j],1,len2,1,b[i]));
            dp[i]=dp[res]+1;nxt[i]=res;
            if (dp[i]>=ans) ans=dp[i],start=i;
            for (int j=a[i];j<=len1;j+=j&-j)
                modify(rt[j],1,len2,b[i],i);
        }
        printf("%d\n",ans);
        for (int i=start;i;i=nxt[i])
        {
            printf("%d",i);
            if (nxt[i]) printf(" ");//防PE
        }
        puts("");
        for (int i=1;i<=len1;++i) rt[i]=0;
    }
    return 0;
}

以上是关于[HDU5324]Boring Class的主要内容,如果未能解决你的问题,请参考以下文章

HDU - 5324 Boring Class

HDU - 5324:Boring Class (CDQ分治&树状数组&最小字典序)

HDU 5324 Boring Classcdq分治

[HDU3518]Boring counting(后缀数组)

[HDU3518]Boring counting

HDU 5056 Boring count(数学)