zoukankan      html  css  js  c++  java
  • 【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;
    }
    
    
  • 相关阅读:
    Codechef EDGEST 树套树 树状数组 线段树 LCA 卡常
    BZOJ4319 cerc2008 Suffix reconstruction 字符串 SA
    Codechef STMINCUT S-T Mincut (CodeChef May Challenge 2018) kruskal
    Codeforces 316G3 Good Substrings 字符串 SAM
    Codechef CHSIGN Change the Signs(May Challenge 2018) 动态规划
    BZOJ1396 识别子串 字符串 SAM 线段树
    CodeForces 516C Drazil and Park 线段树
    CodeForces 516B Drazil and Tiles 其他
    CodeForces 516A Drazil and Factorial 动态规划
    SPOJ LCS2
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8697666.html
Copyright © 2011-2022 走看看