zoukankan      html  css  js  c++  java
  • #树状数组,dp#洛谷 3506 [POI2010]MOT-Monotonicity 2

    题目

    给出(N)个正整数(a[1..N]),再给出(K)个关系符号(>、<或=)(s[1..k])

    选出一个长度为(L)的子序列(不要求连续),要求这个子序列的第(i)项和第(i+1)项的的大小关系为(s[(i-1)mod K+1])

    求出(L)的最大值。并输出一组具体方案。


    分析

    (dp[i])表示以(i)结尾的(L)的最大值,
    (dp[i]=max{dp[j]+1})
    可以发现偏序关系实则是由(dp[j])来决定的,
    而且更小的(dp[j])不能够影响(i)以后的选择
    对于小于号和大于号开两个树状数组记录最大的(dp[j])
    等于号就直接记录上一次出现的位置即可


    代码

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define rr register
    using namespace std;
    const int N=500011; char p[N];
    int dp[N],n,m,k,b[N],a[N],pre[N],ans,pos[N];
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans;
    }
    inline void print(int ans){
    	if (ans>9) print(ans/10);
    	putchar(ans%10+48);
    }
    inline void dfs(int n){
    	if (!n) return;
    	dfs(pre[n]);
    	print(b[a[n]]),putchar(32);
    }
    struct Tree_Array{
    	int c[N];
    	inline void update(int x,int y){
    		for (;x<=k;x+=-x&x)
    		if (dp[c[x]]<dp[y])
    		    c[x]=y;
    	}
    	inline signed query(int x){
    		rr int ans=0;
    		for (;x;x-=-x&x)
    		if (dp[ans]<dp[c[x]])
    		    ans=c[x];
    		return ans;
    	}
    }c0,c1;
    signed main(){
    	n=iut(); m=iut();
    	for (rr int i=1;i<=n;++i) b[i]=a[i]=iut(),dp[i]=1;
    	sort(b+1,b+1+n),k=unique(b+1,b+1+n)-b-1;
    	for (rr int i=1;i<=n;++i) a[i]=lower_bound(b+1,b+1+k,a[i])-b;
    	for (rr int i=1;i<=m;++i){
    		rr char ch=getchar();
    		while (ch!='<'&&ch!='>'&&ch!='=') ch=getchar();
    		for (rr int j=i;j<=n;j+=m) p[j]=ch;
    	}
    	for (rr int i=1,j;i<=n;++i){
    		if (dp[i]<dp[j=c0.query(a[i]-1)]+1) dp[i]=dp[j]+1,pre[i]=j;
    		if (dp[i]<dp[j=c1.query(k-a[i])]+1) dp[i]=dp[j]+1,pre[i]=j;
    		if (dp[i]<dp[j=pos[a[i]]]+1) dp[i]=dp[j]+1,pre[i]=j;
    		if (p[dp[i]]=='<') c0.update(a[i],i);
    		if (p[dp[i]]=='>') c1.update(k-a[i]+1,i);
    		if (p[dp[i]]=='=') pos[a[i]]=i;
    		if (dp[ans]<dp[i]) ans=i;
    	}
    	print(dp[ans]),putchar(10),dfs(ans);
    	return 0;
    }
    
  • 相关阅读:
    ES6 快速入门
    export,import ,export default区别
    React 生命周期
    Nodejs npm常用命令
    JavaScript:改变 HTML 图像
    WebStorm安装、配置node.js(Windows)
    Flex 布局
    块级元素与行内元素区别
    自动化测试弹框处理
    python远程操作服务器
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/14980621.html
Copyright © 2011-2022 走看看