zoukankan      html  css  js  c++  java
  • 【YbtOJ#20061】波动序列

    题目

    题目链接:http://noip.ybtoj.com.cn/contest/86/problem/3

    思路

    \(f[i][j][1/2/3/4]\) 表示前 \(i\) 个数,最后一个数选的是 \(j\),且最后一个数是在第一行 / 第二行 / 第三行升序 / 第三行降序的最大选中个数。
    容易推出 \(O(nm)\) 转移。发现转移中对于每一个不同的列 \(i\),只有 \(4\) 个位置需要修改,所以开四棵线段树维护 dp 值即可。
    每次转移只需要区间求 \(\max\),单点修改。时间复杂度 \(O(n\log n)\)

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=100010;
    int n,m,a[4][N],b[N*3];
    
    int read()
    {
    	int d=0,f=1; char ch=getchar();
    	while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar(); }
    	while (isdigit(ch)) d=(d<<3)+(d<<1)+ch-48,ch=getchar();
    	return d*f;
    }
    
    struct SegTree
    {
    	int maxn[N*12];	
    	
    	void update(int x,int l,int r,int k,int v)
    	{
    		maxn[x]=max(maxn[x],v);
    		if (l==k && r==k) return;
    		int mid=(l+r)>>1;
    		if (k<=mid) update(x*2,l,mid,k,v);
    			else update(x*2+1,mid+1,r,k,v);
    	}
    	
    	int query(int x,int l,int r,int ql,int qr)
    	{
    		if (l==ql && r==qr) return maxn[x];
    		int mid=(l+r)>>1;
    		if (qr<=mid) return query(x*2,l,mid,ql,qr);
    		if (ql>mid) return query(x*2+1,mid+1,r,ql,qr);
    		return max(query(x*2,l,mid,ql,mid),query(x*2+1,mid+1,r,mid+1,qr));
    	}
    }seg1,seg2,seg3,seg4;
    
    int Maxquery(int ql,int qr,bool f1,bool f2,bool f3,bool f4)
    {
    	int maxf=0;
    	if (f1) maxf=max(maxf,seg1.query(1,1,m,ql,qr)+1);
    	if (f2) maxf=max(maxf,seg2.query(1,1,m,ql,qr)+1);
    	if (f3) maxf=max(maxf,seg3.query(1,1,m,ql,qr)+1);
    	if (f4) maxf=max(maxf,seg4.query(1,1,m,ql,qr)+1);
    	return maxf;
    }
    
    int main()
    {
    	freopen("sequence.in","r",stdin);
    	freopen("sequence.out","w",stdout);
    	n=read();
    	for (int i=1;i<=3;i++)
    		for (int j=1;j<=n;j++)
    			b[++m]=a[i][j]=read();
    	sort(b+1,b+1+m);
    	m=unique(b+1,b+1+m)-b-1;
    	for (int i=1;i<=3;i++)
    		for (int j=1;j<=n;j++)
    			a[i][j]=lower_bound(b+1,b+1+m,a[i][j])-b;
    	for (int i=1;i<=n;i++)
    	{
    		int f1=Maxquery(1,a[1][i],1,1,1,1),f2=Maxquery(a[2][i],m,1,1,1,1);
    		int f3=Maxquery(1,a[3][i],1,1,1,0),f4=Maxquery(a[3][i],m,1,1,0,1);
    		seg1.update(1,1,m,a[1][i],max(f1,1)); seg2.update(1,1,m,a[2][i],max(f2,1));
    		seg3.update(1,1,m,a[3][i],max(f3,1)); seg4.update(1,1,m,a[3][i],max(f4,1));
    	}
    	printf("%d",Maxquery(1,m,1,1,1,1)-1);
    	return 0;
    }
    
  • 相关阅读:
    ffmpeg 日志系统av_log()
    语音识别哪家强 讯飞 搜狗 百度 阿里还是腾讯
    利用FFmpeg切割视频
    网易云音乐 抓取成功,按评论数排序
    python from import 自定义模块
    使用Fiddler调试线上JS代码
    sublime text 格式化html css 与显示函数列表
    微信硬件(四)调试工具
    微信硬件平台(三) 菜单开发
    微信硬件(三)
  • 原文地址:https://www.cnblogs.com/stoorz/p/13809059.html
Copyright © 2011-2022 走看看