• 【CF484E】Sign on Fence(主席树)


    【CF484E】Sign on Fence(主席树)

    题面

    懒得贴CF了,你们自己都找得到
    洛谷

    题解

    这不就是[TJOI&HEOI 排序]那题的套路吗。。。
    二分一个答案,把大于答案的都变成(1),其余变成(0)
    按照题目要求的区间内连续的(K)
    就是检查最长的连续(1)的子段长度大于(K)
    所以维护(1)的子段长度(这也是原题吧??)

    因为范围比较大,不能每次开线段树计算
    我们发现每次将范围增大的时候,在线段树上可以直接做一定的修改
    又因为要维护所有的线段树,所以直接主席树维护即可

    #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 111111
    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;
    }
    struct Node
    {
    	int ls,rs,l,r,id;
    	int lm,rm,mm;
    }t[MAX*20];
    int tot,rt[MAX];
    Node operator+(Node a,Node b)
    {
    	Node c;c.ls=a.id;c.rs=b.id;
    	c.l=a.l;c.r=b.r;c.lm=a.lm;c.rm=b.rm;
    	if(a.lm==a.r-a.l+1)c.lm+=b.lm;
    	if(b.lm==b.r-b.l+1)c.rm+=a.rm;
    	c.mm=max(max(a.mm,b.mm),a.rm+b.lm);
    	return c;
    }
    void Modify(int &x,int ff,int l,int r,int p)
    {
    	t[x=++tot]=t[ff];t[x].l=l;t[x].r=r;t[x].id=x;
    	if(l==r){t[x].lm=t[x].rm=t[x].mm=1;return;}
    	int mid=(l+r)>>1;
    	if(p<=mid)Modify(t[x].ls,t[ff].ls,l,mid,p);
    	else Modify(t[x].rs,t[ff].rs,mid+1,r,p);
    	t[x]=t[t[x].ls]+t[t[x].rs];t[x].id=x;
    }
    Node Query(int x,int l,int r,int L,int R)
    {
    	if(l==L&&r==R)return t[x];
    	int mid=(l+r)>>1;
    	if(R<=mid)return Query(t[x].ls,l,mid,L,R);
    	if(L>mid)return Query(t[x].rs,mid+1,r,L,R);
    	return Query(t[x].ls,l,mid,L,mid)+Query(t[x].rs,mid+1,r,mid+1,R);
    }
    int n,a[MAX],S[MAX],p[MAX];
    bool cmp(int x,int y){return a[x]<a[y];}
    int main()
    {
    	n=read();
    	for(int i=1;i<=n;++i)S[i]=a[i]=read(),p[i]=i;
    	sort(&S[1],&S[n+1]);
    	int sum=unique(&S[1],&S[n+1])-S-1;
    	for(int i=1;i<=n;++i)a[i]=lower_bound(&S[1],&S[sum+1],a[i])-S;
    	sort(&p[1],&p[n+1],cmp);
    	for(int i=n;i;--i)
    	{
    		if(a[p[i]]!=a[p[i+1]])Modify(rt[a[p[i]]],rt[a[p[i+1]]],1,n,p[i]);
    		else Modify(rt[a[p[i]]],rt[a[p[i]]],1,n,p[i]);
    	}
    	int Q=read();
    	while(Q--)
    	{
    		int L=read(),R=read(),K=read();
    		int l=1,r=sum,ans=1;
    		while(l<=r)
    		{
    			int mid=(l+r)>>1;
    			if(Query(rt[mid],1,n,L,R).mm>=K)ans=mid,l=mid+1;
    			else r=mid-1;
    		}
    		printf("%d
    ",S[ans]);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    ArrayList 和 Vector 的区别
    Redis在springboot中使用,读取字符串
    初始化Mysql
    Redis 安装
    React-脚手架
    React virtual DOM explained in simple English/简单语言解释React的虚拟DOM
    数据结构
    书单(18-19)
    算法复杂度
    otrs离线部署
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8697666.html
Copyright © 2020-2023  润新知