zoukankan      html  css  js  c++  java
  • BZOJ 2653 middle

    《做人要有梦想系列》

     题解:

       强制在线多组询问求开端在[a,b],结束在[c,d]的子序列的最大中位数。

       若有两个中位数取最大的中位数。

     1.如何处理中位数最大的限制?

       答:二分答案,将大于等于x的数设为1,将小于x的数设为-1,[b,c]的一定要,[a,b)要rmax,(c,d]要lmax即可.

       2.如何快速求上述东西?

     答:开一个按权值大小排序的区间为值的主席树,然后在上面记录lmax,rmax即可.

        时间:O(nlog2n) 空间:O(nlogn)。

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 #define ll long long
     5 #define FILE "dealing"
     6 #define up(i,j,n) for(int i=j;i<=n;i++)
     7 #define db long double 
     8 #define pii pair<int,int>
     9 #define pb push_back
    10 #define mem(a,L) memset(a,0,sizeof(int)*(L+1))
    11 template<class T> inline bool cmin(T& a,T b){return a>b?a=b,true:false;}
    12 template<class T> inline bool cmax(T& a,T b){return a<b?a=b,true:false;}
    13 template<class T> inline T squ(T a){return a*a;}
    14 const ll maxn=2000100+10,MAXN=200200,inf=1e9+10,limit=1e7,base=23;
    15 int read(){
    16     int x=0,f=1,ch=getchar();
    17     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    18     while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    19     return x*f;
    20 }
    21 int n,Q;
    22 int v[MAXN];
    23 int q[4];
    24 pii t[MAXN];
    25 int cnt,c[maxn][2],root[maxn];
    26 struct node{
    27     int lmax,rmax,sum;
    28     node(int lmax=0,int rmax=0,int sum=0):lmax(lmax),rmax(rmax),sum(sum){}
    29 }a[maxn];
    30 node updata(node le,node ri){
    31     node k;
    32     k.lmax=max(le.lmax,le.sum+ri.lmax);
    33     k.rmax=max(ri.rmax,ri.sum+le.rmax);
    34     k.sum=le.sum+ri.sum;
    35     return k;
    36 }
    37 
    38 void insert(int pre,int& o,int l,int r,int key){
    39     o=++cnt;
    40     if(l==r){
    41         a[o].lmax=a[o].rmax=a[o].sum=1;
    42         return;
    43     }
    44     int mid=(l+r)>>1;
    45     if(key>mid)c[o][0]=c[pre][0],insert(c[pre][1],c[o][1],mid+1,r,key);
    46     else c[o][1]=c[pre][1],insert(c[pre][0],c[o][0],l,mid,key);
    47     if(c[o][0]&&c[o][1])a[o]=updata(a[c[o][0]],a[c[o][1]]);
    48     else if(!c[o][0]&&c[o][1])a[o]=updata(node(0,0,-(mid-l+1)),a[c[o][1]]);
    49     else a[o]=updata(a[c[o][0]],node(0,0,-(r-mid)));
    50 }
    51 node query(int o,int l,int r,int L,int R){
    52     if(l>R||r<L)return node(0,0,0);
    53     if(!o)return node(0,0,-(min(r,R)-max(L,l)+1));
    54     if(l>=L&&r<=R)return a[o];
    55     int mid=(l+r)>>1;
    56     return updata(query(c[o][0],l,mid,L,R),query(c[o][1],mid+1,r,L,R));
    57 }
    58 bool cmp(const pii& a,const pii& b){return a.first>b.first;}
    59 int main(){
    60     freopen(FILE".in","r",stdin);
    61     freopen(FILE".out","w",stdout);
    62     n=read();
    63     up(i,1,n)v[i]=read(),t[i].first=v[i],t[i].second=i;
    64     sort(t+1,t+n+1,cmp);
    65     up(i,1,n)insert(root[i-1],root[i],1,n,t[i].second);
    66     Q=read();int lastans=0;
    67     up(i,1,Q){
    68         up(j,0,3)q[j]=(read()+lastans)%n;
    69         sort(q,q+4);
    70         up(j,0,3)q[j]++;
    71         int left=1,right=n,ans=0;
    72         while(left<=right){
    73             int mid=(left+right)>>1;
    74             node k=query(root[mid],1,n,q[1],q[2]);
    75             node le=query(root[mid],1,n,q[0],q[1]-1);
    76             node ri=query(root[mid],1,n,q[2]+1,q[3]);
    77             int sum=k.sum+le.rmax+ri.lmax;
    78             if(sum>=0)right=mid-1,ans=mid;
    79             else left=mid+1;
    80         }
    81         printf("%d
    ",lastans=t[ans].first);
    82     }
    83     return 0;
    84 }
    View Code
  • 相关阅读:
    flask 使用 SQLAlchemy 的两种方式
    python package 的两种组织方式
    sqlalchemy 的 raw sql 方式使用示例
    Git高速入门——Git安装、创建版本号库以及经常使用命令
    mariadb 10.1.10安装
    Android studio中导入第三方类库
    怎样获取oracle dbid
    宇宙中为何存在“黑洞”?
    CSDN日报20170401 ——《假设你还是“程序猿”,我劝你别创业!》
    clang-format中文出错
  • 原文地址:https://www.cnblogs.com/chadinblog/p/6810239.html
Copyright © 2011-2022 走看看