• [HDU5324]Boring Class


    vjudge

    sol

    字典序最小可以通过倒着(dp)解决。对每个(i)记录它可以转移到的(dp)值最大且字典序最小的(nxt_i)
    尝试着写一下(dp)式子。

    [dp_i=max{dp_j}+1(j>i,L_jle L_i,R_jge 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
    ",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;
    }
    
  • 相关阅读:
    Linux let 命令
    perl hash array 嵌套 push
    Perl CGI编程
    Perl关联数组用法集锦
    关于反射和动态代理
    SpringBoot与web开发
    Springboot与日志
    Spring Boot
    SpringBoot的自动配置原理
    Spring MVC执行流程
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8567899.html
Copyright © 2020-2023  润新知