zoukankan      html  css  js  c++  java
  • BZOJ 2223 [Coci 2009]PATULJCI | 主席树练习 (好像是个权限题啊)

    题目:

    给个序列,问[l,r]区间内是否存在x>(r-l+1)>>1


    题解:

    好像大家都觉得这个题比较简单,没人写题解啊

    先说BZOJ样例的格式应该是,第二个数是序列中数的范围(就是不用离散化)

    10 3

    1 2 1 2 1 2 3 2 3 3

    8

    1 2

    1 3

    1 4

    1 5

    2 5

    2 6

    6 9

    7 10

    这是经典的主席树问题,

    按序列顺序依次让a[i]位置++,维护区间数的数目

    我们二分答案然后从root[l-1]和root[r]开走

    显然答案x满足sum[代表点x的节点]>(sum[r]-sum[l-1])/2

    如果右子树-右子树满足要求,那就走到右子树,然后答案应该变大

    同理左子树,如果都不行就没答案了

    #include<cstdio>
    #define N 300000*20
    using namespace std;
    int root[N],lc[N],rc[N],sum[N],n,m,x,pcnt,Lim;
    void insert(int x,int &y,int l,int r,int k)
    {
        lc[y=++pcnt]=lc[x],rc[y]=rc[x],sum[y]=sum[x]+1;
        if (l==r) return ;
        int mid=l+r>>1;
        if (k<=mid) insert(lc[x],lc[y],l,mid,k);
        else insert(rc[x],rc[y],mid+1,r,k);
    }
    int query(int L,int R)
    {
        int l=1,r=Lim,mid,lim=(R-L+1)>>1,x=root[L-1],y=root[R];
        while (l<r)
        {
            if (sum[y]-sum[x]<=lim) return 0;
            mid=l+r>>1;
            if (sum[lc[y]]-sum[lc[x]]>lim)
                r=mid,x=lc[x],y=lc[y];
            else if (sum[rc[y]]-sum[rc[x]]>lim)
                l=mid+1,x=rc[x],y=rc[y];
            else return 0;
        }
        return l;
    }
    int main()
    {
        scanf("%d%d",&n,&Lim);
        for (int i=1;i<=n;i++)
            scanf("%d",&x),insert(root[i-1],root[i],1,Lim,x);
        scanf("%d",&m);
        for (int i=1,l,r;i<=m;i++)
            scanf("%d%d",&l,&r),(x=query(l,r))?printf("yes %d
    ",x):puts("no");
        return 0;
    } 
  • 相关阅读:
    使用 Docker 部署 Spring Boot
    阿里云Redis开发规范
    Java开发包Jedis
    Jedis的配置和优化
    JVM调优前戏之JDK命令行工具---jhat
    JVM调优前戏之JDK命令行工具---jstack
    JVM调优之经验
    Logback配置文件这么写,TPS提高10倍
    Java开发包Jedis
    Error Handling in ASP.NET Core
  • 原文地址:https://www.cnblogs.com/mrsheep/p/8151243.html
Copyright © 2011-2022 走看看