zoukankan      html  css  js  c++  java
  • bzoj2653

    middle

     HYSBZ - 2653 

    一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整。给你一个
    长度为n的序列s。回答Q个这样的询问:s的左端点在[a,b]之间,右端点在[c,d]之间的子序列中,最大的中位数。
    其中a<b<c<d。位置也从0开始标号。我会使用一些方式强制你在线。

     

    Input
    第一行序列长度n。接下来n行按顺序给出a中的数。
    接下来一行Q。然后Q行每行a,b,c,d,我们令上个询问的答案是
    x(如果这是第一个询问则x=0)。
    令数组q={(a+x)%n,(b+x)%n,(c+x)%n,(d+x)%n}。
    将q从小到大排序之后,令真正的
    要询问的a=q[0],b=q[1],c=q[2],d=q[3]。  
    输入保证满足条件。
    第一行所谓“排过序”指的是从小到大排序!
    n<=20000,Q<=25000
     

     

    Output

    Q行依次给出询问的答案。

     

    Sample Input
    5
    170337785 271451044 22430280 969056313 206452321
    3
    3 1 0 2
    2 3 1 4
    3 1 4 0

    Sample Output

    271451044

    271451044

    969056313

    sol : 一个区间的中位数要求这段区间比他大的个数>=比他小的个数,所以我们可以二分答案,对于每个数字建一颗线段树,如[a,b]和[c,d]中的那段区间,就是所有数字中比他大的减去比他小的,在减去[a,b]中的前缀min和[c,d]中的后缀min,但是对于每次都重建一棵树肯定会T出shi,所以弄棵主席树可持久化,先建一个全-1的树,然后按数值大小从大到小做,一次把一个-1改成1,相当于修改一个区间,比如修改位置P,就是改掉[1,P]的后缀min和[P,n]的前缀min

    Ps:实现的时候犯错调了好久,详见注释

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    inline ll read()
    {
        ll s=0;
        bool f=0;
        char ch=' ';
        while(!isdigit(ch))
        {
            f|=(ch=='-'); ch=getchar();
        }
        while(isdigit(ch))
        {
            s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
        }
        return (f)?(-s):(s);
    }
    #define R(x) x=read()
    inline void write(ll x)
    {
        if(x<0)
        {
            putchar('-'); x=-x;
        }
        if(x<10)
        {
            putchar(x+'0'); return;
        }
        write(x/10);
        putchar((x%10)+'0');
        return;
    }
    #define W(x) write(x),putchar(' ')
    #define Wl(x) write(x),putchar('
    ')
    const int N=20005;
    #define pii pair<int,int>
    #define fi first
    #define se second
    int n,m;
    struct Shuz
    {
        int Num,Pos;
        inline bool operator<(const Shuz &tmp)const
        {
            return Num>tmp.Num;
        }
    }A[N];
    int rt[N],cnt=0;
    struct Node
    {
        int ls,rs;
        pii Pre,Suf;
    }T[N*105];
    inline void PushUp(int x)
    {
        T[x].Pre.fi=min(T[T[x].ls].Pre.fi,T[T[x].rs].Pre.fi);
        T[x].Suf.fi=min(T[T[x].ls].Suf.fi,T[T[x].rs].Suf.fi);
    }
    inline void PushDown(int x)
    {
        if((!T[x].Pre.se)&&(!T[x].Suf.se)) return;
        int o1=T[x].Pre.se,o2=T[x].Suf.se;
        int lc=++cnt,rc=++cnt;
        T[lc]=T[T[x].ls]; T[rc]=T[T[x].rs];
        if(o1)
        {
            T[lc].Pre.fi+=o1; T[lc].Pre.se+=o1; T[rc].Pre.fi+=o1; T[rc].Pre.se+=o1;
        }
        if(o2)
        {
            T[lc].Suf.fi+=o2; T[lc].Suf.se+=o2; T[rc].Suf.fi+=o2; T[rc].Suf.se+=o2;
        }
        T[x].ls=lc; T[x].rs=rc;
        T[x].Pre.se=T[x].Suf.se=0;
    }
    inline void Build(int &x,int l,int r)
    {
        x=++cnt;
        T[x].Pre.fi=-r; T[x].Pre.se=0; T[x].Suf.fi=-(n-l+1); T[x].Suf.se=0;
        if(l==r) return;
        int mid=(l+r)>>1;
        Build(T[x].ls,l,mid);
        Build(T[x].rs,mid+1,r);
    }
    inline void ChgPre(int &x,int y,int l,int r,int ql,int qr)
    {
        x=++cnt; T[x]=T[y];
        if(l==ql&&r==qr)
        {
            T[x].Pre.fi+=2; T[x].Pre.se+=2; return;
        }
        PushDown(y); T[x]=T[y]; //要把y中的标记传下去,否则之后把T[y].ls弄回T[x].ls会萎掉!!! 
        int mid=(l+r)>>1;
        if(qr<=mid) ChgPre(T[x].ls,T[y].ls,l,mid,ql,qr);
        else if(ql>mid) ChgPre(T[x].rs,T[y].rs,mid+1,r,ql,qr);
        else ChgPre(T[x].ls,T[y].ls,l,mid,ql,mid),ChgPre(T[x].rs,T[y].rs,mid+1,r,mid+1,qr);
        PushUp(x);
    }
    inline void ChgSuf(int &x,int y,int l,int r,int ql,int qr)
    {
        x=++cnt; T[x]=T[y];
        if(l==ql&&r==qr)
        {
            T[x].Suf.fi+=2; T[x].Suf.se+=2; return;
        }
        PushDown(y); T[x]=T[y];
        int mid=(l+r)>>1;
        if(qr<=mid) ChgSuf(T[x].ls,T[y].ls,l,mid,ql,qr);
        else if(ql>mid) ChgSuf(T[x].rs,T[y].rs,mid+1,r,ql,qr);
        else ChgSuf(T[x].ls,T[y].ls,l,mid,ql,mid),ChgSuf(T[x].rs,T[y].rs,mid+1,r,mid+1,qr);
        PushUp(x);
    }
    inline int QueryPre(int x,int l,int r,int ql,int qr)
    {
        if(l==ql&&r==qr) return T[x].Pre.fi;
        int mid=(l+r)>>1;
        PushDown(x);
        if(qr<=mid) return QueryPre(T[x].ls,l,mid,ql,qr);
        else if(ql>mid) return QueryPre(T[x].rs,mid+1,r,ql,qr);
        else return min(QueryPre(T[x].ls,l,mid,ql,mid),QueryPre(T[x].rs,mid+1,r,mid+1,qr));
        PushUp(x);
    }
    inline int AskPre(int x,int l,int r,int ql,int qr)
    {
        if(qr==1) return 0;
        if(ql==1) return min(QueryPre(x,l,r,ql,qr-1),0);
        return QueryPre(x,l,r,ql-1,qr-1);
    }
    inline int QuerySuf(int x,int l,int r,int ql,int qr)
    {
        if(l==ql&&r==qr) return T[x].Suf.fi;
        int mid=(l+r)>>1;
        PushDown(x);
        if(qr<=mid) return QuerySuf(T[x].ls,l,mid,ql,qr);
        else if(ql>mid) return QuerySuf(T[x].rs,mid+1,r,ql,qr);
        else return min(QuerySuf(T[x].ls,l,mid,ql,mid),QuerySuf(T[x].rs,mid+1,r,mid+1,qr));
        PushUp(x);
    }
    inline int AskSuf(int x,int l,int r,int ql,int qr)
    {
        if(ql==n) return 0;
        if(qr==n) return min(QuerySuf(x,l,r,ql+1,qr),0);
        return QuerySuf(x,l,r,ql+1,qr+1);
    }
    int main()
    {
        freopen("2653.in","r",stdin);
        freopen("2653.out","w",stdout);
        int i,j,ans=0;
        R(n);
        for(i=1;i<=n;i++) A[i]=(Shuz){read(),i};
        sort(A+1,A+n+1);
    //    for(i=1;i<=n;i++) cout<<A[i].Num<<' '; puts("");
        Build(rt[0],1,n);
        for(i=1;i<=n;i++)
        {
            int tot;
            ChgPre(tot,rt[i-1],1,n,A[i].Pos,n);
            ChgSuf(rt[i],tot,1,n,1,A[i].Pos);
        }
        R(m);
        for(i=1;i<=m;i++)
        {
            int a,b,c,d,q[5];
            for(j=1;j<=4;j++) q[j]=(read()+ans)%n+1; sort(q+1,q+5); a=q[1]; b=q[2]; c=q[3]; d=q[4];
            int l=1,r=n,pp;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                int tmp=mid-(n-mid); //倒序的
                if((tmp-AskPre(rt[mid],1,n,a,b)-AskSuf(rt[mid],1,n,c,d))>=0) pp=mid,r=mid-1; //注意是倒序的 
                else l=mid+1;
            }
            Wl(ans=A[pp].Num);
    //        return 0;
        }
        return 0;
    }
    /*
    input
    5
    170337785
    271451044
    22430280
    969056313
    206452321
    3
    3 1 0 2
    2 3 1 4
    3 1 4 0
    Output
    271451044
    271451044
    969056313
    */
    View Code
  • 相关阅读:
    [轉]windows下mysql 启动 mysqlbinlog二进制日志文件
    [轉]MySQL创建、删除、重建和查看索引命令
    [轉]PHP权限控制系统PHPGACL
    [轉]mysql5存储过程语法
    Web Application Stress Tool(WAS) & SQLIOSim
    information_schema資料庫表信息
    [轉]MySQL系统变量应用探究
    [轉]httping 1.5.2 发布,HTTP连接响应测试
    [轉]批处理命令手册
    Google Native Client介紹
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/11187741.html
Copyright © 2011-2022 走看看