• 【BZOJ4991】我也不知道题目名字是什么(线段树)


    【BZOJ4991】我也不知道题目名字是什么(线段树)

    题面

    BZOJ

    题解

    对于线段树维护的区间维护以下东西:

    区间左(右)端开始(结束)的最长(短)子串的长度

    左端右端的值,以及当前区间内的答案

    每次向上合并只需要分类讨论即可

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define MAX 55000
    #define lson (now<<1)
    #define rson (now<<1|1)
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    int n;
    struct Node
    {
    	int l,r;
    	int lv,rv;
    	int ls,rs,ms;
    	int lj,rj,mj;
    }t[MAX<<2];
    Node operator+(Node a,Node b)
    {
    	Node c;
    	c.l=a.l;c.r=b.r;
    	c.lv=a.lv;c.rv=b.rv;
    	c.ls=a.ls;c.rs=b.rs;
    	if(a.ls==a.r-a.l+1&&a.rv<=b.lv)c.ls+=b.ls;
    	if(b.rs==b.r-b.l+1&&a.rv<=b.lv)c.rs+=a.rs;
    	c.ms=max(a.ms,b.ms);
    	c.ms=max(c.ms,max(c.ls,c.rs));
    	if(a.rv<=b.lv)c.ms=max(c.ms,a.rs+b.ls);
    	c.lj=a.lj;c.rj=b.rj;
    	if(a.lj==a.r-a.l+1&&a.rv>=b.lv)c.lj+=b.lj;
    	if(b.rj==b.r-b.l+1&&a.rv>=b.lv)c.rj+=a.rj;
    	c.mj=max(a.mj,b.mj);
    	c.mj=max(c.mj,max(c.lj,c.rj));
    	if(a.rv>=b.lv)c.mj=max(c.mj,a.rj+b.lj);
    	return c;
    }
    void Build(int now,int l,int r)
    {
    	t[now].l=l;t[now].r=r;
    	if(l==r)
    	{
    		t[now].lv=t[now].rv=read();
    		t[now].mj=t[now].lj=t[now].rj=1;
    		t[now].ms=t[now].ls=t[now].rs=1;
    		return;
    	}
    	int mid=(l+r)>>1;
    	Build(lson,l,mid);Build(rson,mid+1,r);
    	t[now]=t[lson]+t[rson];
    }
    Node Query(int now,int l,int r,int L,int R)
    {
    	if(L==l&&r==R)return t[now];
    	int mid=(l+r)>>1;
    	if(R<=mid)return Query(lson,l,mid,L,R);
    	if(L>mid)return Query(rson,mid+1,r,L,R);
    	return Query(lson,l,mid,L,mid)+Query(rson,mid+1,r,mid+1,R);
    }
    int main()
    {
    	n=read();Build(1,1,n);
    	int m=read();
    	while(m--)
    	{
    		int l=read(),r=read();
    		Node ans=Query(1,1,n,l,r);
    		printf("%d
    ",max(ans.ms,ans.mj));
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    在AS/400上根据日期生成星期几
    如何删除含无效字符的文件
    在CL中使用SST或者SUBSTRING
    取网络属性
    如何在程序中获取系统ASP使用率等系统状态信息
    在CL中使用ELSE
    在CL中读一个文件
    如何在FTP命令行执行AS/400命令
    广告悬停功能
    关于Grouping, Rollup,cube,
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8557256.html
Copyright © 2020-2023  润新知