zoukankan      html  css  js  c++  java
  • 解题:国家集训队 Middle

    题面

    求中位数的套路:二分,大于等于的设为1,小于的设为-1

    于是可以从小到大排序后依次加入可持久化线段树,这样每次只会变化一个位置

    那左右端点是区间怎么办?

    先把中间的算上,然后维护每个区间左右两侧最大子段和,左右和右左拼起来即可

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 using namespace std;
      5 const int N=20005,M=1e7+70,inf=1e9;
      6 int num[N],root[N],son[M][2],sum[M],lsum[M],rsum[M],qry[10];
      7 int n,m,t1,t2,t3,t4,rd,tot,ans; pair<int,int> mem[N];
      8 void Pushup(int nde)
      9 {
     10     int ls=son[nde][0],rs=son[nde][1];
     11     sum[nde]=sum[ls]+sum[rs];
     12     lsum[nde]=max(lsum[ls],sum[ls]+lsum[rs]);
     13     rsum[nde]=max(rsum[rs],sum[rs]+rsum[ls]);
     14 }
     15 int Pre(int l,int r)
     16 {
     17     int nde=++tot;
     18     if(l==r)
     19         sum[nde]=lsum[nde]=rsum[nde]=1;
     20     else
     21     {
     22         int mid=(l+r)>>1;
     23         son[nde][0]=Pre(l,mid);
     24         son[nde][1]=Pre(mid+1,r);
     25         Pushup(nde); 
     26     }
     27     return nde;
     28 }
     29 int Insert(int pre,int l,int r,int pos,int tsk)
     30 {
     31     int nde=++tot;
     32     son[nde][0]=son[pre][0];
     33     son[nde][1]=son[pre][1];
     34     if(l==r)
     35         sum[nde]=lsum[nde]=rsum[nde]=tsk;
     36     else
     37     {
     38         int mid=(l+r)>>1;
     39         if(pos<=mid) son[nde][0]=Insert(son[pre][0],l,mid,pos,tsk);
     40         else son[nde][1]=Insert(son[pre][1],mid+1,r,pos,tsk); Pushup(nde);
     41     }
     42     return nde;
     43 }
     44 int Query1(int nde,int l,int r,int ll,int rr)
     45 {
     46     if(l==ll&&r==rr)
     47         return sum[nde];
     48     else
     49     {
     50         int mid=(l+r)>>1;
     51         if(mid>=rr) return Query1(son[nde][0],l,mid,ll,rr);
     52         else if(mid<ll) return Query1(son[nde][1],mid+1,r,ll,rr);
     53         else return Query1(son[nde][0],l,mid,ll,mid)+Query1(son[nde][1],mid+1,r,mid+1,rr);
     54     }
     55 }
     56 int Query2(int nde,int l,int r,int ll,int rr)
     57 {
     58     if(l==ll&&r==rr)
     59         return lsum[nde];
     60     else
     61     {
     62         int mid=(l+r)>>1;
     63         if(mid>=rr) return Query2(son[nde][0],l,mid,ll,rr);
     64         else if(mid<ll) return Query2(son[nde][1],mid+1,r,ll,rr);
     65         else return max(Query2(son[nde][0],l,mid,ll,mid),Query1(son[nde][0],l,mid,ll,mid)+Query2(son[nde][1],mid+1,r,mid+1,rr));
     66     }
     67 }
     68 int Query3(int nde,int l,int r,int ll,int rr)
     69 {
     70     if(l==ll&&r==rr)
     71         return rsum[nde];
     72     else
     73     {
     74         int mid=(l+r)>>1;
     75         if(mid>=rr) return Query3(son[nde][0],l,mid,ll,rr);
     76         else if(mid<ll) return Query3(son[nde][1],mid+1,r,ll,rr);
     77         else return max(Query3(son[nde][1],mid+1,r,mid+1,rr),Query1(son[nde][1],mid+1,r,mid+1,rr)+Query3(son[nde][0],l,mid,ll,mid));
     78     }
     79 }
     80 bool Check(int x)
     81 {
     82     int ret=0;
     83     if(qry[2]+1<=qry[3]-1) ret+=Query1(root[x],1,n,qry[2]+1,qry[3]-1);
     84     ret+=Query3(root[x],1,n,qry[1],qry[2])+Query2(root[x],1,n,qry[3],qry[4]);
     85     return ret>=0;
     86 }
     87 int main()
     88 {
     89     scanf("%d",&n);
     90     for(int i=1;i<=n;i++)
     91         scanf("%d",&num[i]),mem[i]=make_pair(num[i],i);
     92     sort(mem+1,mem+1+n),root[1]=Pre(1,n);
     93     for(int i=2;i<=n;i++)
     94         root[i]=Insert(root[i-1],1,n,mem[i-1].second,-1);
     95     scanf("%d",&m);
     96     for(int i=1;i<=m;i++)
     97     {
     98         for(int j=1;j<=4;j++) 
     99             scanf("%d",&rd),qry[j]=(rd+ans)%n+1;
    100         sort(qry+1,qry+5);
    101         int l=1,r=n,lst=1;
    102         while(l<=r)
    103         {
    104             int mid=(l+r)>>1;
    105             if(Check(mid)) l=mid+1,lst=mid;
    106             else r=mid-1;
    107         }
    108         printf("%d
    ",ans=mem[lst].first);
    109     }
    110     return 0;
    111 }
    View Code
  • 相关阅读:
    HDFS常用命令总结
    mac 安装zmap
    使用scrapy-redis搭建分布式爬虫环境
    xpath选择兄弟节点、返回上一级和选择多个属性
    什么是套接字(Socket)
    socket编程——一个简单的例子
    python之 __getattr__、__getattr__、__getitem__、__setitem__ 使用
    如何快速转载文章
    如何让类也变成可以迭代的对象
    leecode 第二题 简单
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10534813.html
Copyright © 2011-2022 走看看