【BZOJ2653】middle

Description

一个长度为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]。  
输入保证满足条件。
第一行所谓“排过序”指的是从大到小排序!

Output

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

Sample Input

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

Sample Output

HINT

0:n,Q<=100
1,...,5:n<=2000
0,...,19:n<=20000,Q<=25000

题解:好吧这题不看题解还真的很难想~

首先二分中位数还是挺好像的,但问题是怎么判断一个中位数是否可行。一个中位数mid可行的条件是序列中(≥mid的数的个数)≥(<mid的数的个数),也就是说,我们将比≥mid的数看成1,<mid的数看成-1,那么需要存在一段区间,使得区间和非负。这又和可持久化线段树有什么关系呢?

我们将所有数排序,然后令1-n的初值都是1,然后将n个数从小到大扔到可持久化线段树中去,并将对应位置变成-1,这样就很好的满足了所给条件。现在问题就是如何判断[a,b]-[c,d]中有没有符合条件的区间,只需要对线段树维护区间连续子段和,最大连续前缀子段和,最大后缀子段和,然后搞一搞就行了。(小白逛公园的简化)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=20010;
int n,m,maxx,minn,tot,ans;
struct sag
{
int ls,rs,sum,lm,rm,sm;
}s[maxn*1000];
struct node
{
int num,org;
}p[maxn];
int q[10],rt[maxn];
int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int max(int a,int b,int c)
{
return max(max(a,b),c);
}
void pushup(int x)
{
s[x].lm=max(s[s[x].ls].lm,s[s[x].ls].sum+s[s[x].rs].lm,0);
s[x].rm=max(s[s[x].rs].rm,s[s[x].rs].sum+s[s[x].ls].rm,0);
s[x].sm=max(s[s[x].ls].sm,s[s[x].rs].sm,s[s[x].ls].rm+s[s[x].rs].lm);
s[x].sum=s[s[x].ls].sum+s[s[x].rs].sum;
}
void build(int l,int r,int &x)
{
if(!x) x=++tot;
if(l==r)
{
s[x].sum=s[x].sm=s[x].lm=s[x].rm=1;
return;
}
int mid=l+r>>1;
build(l,mid,s[x].ls),build(mid+1,r,s[x].rs);
pushup(x);
}
void insert(int x,int &y,int l,int r,int pos)
{
if(r<pos) return ;
y=++tot;
if(l==r)
{
s[y].sum=-1,s[y].lm=s[y].rm=s[y].sm=0;
return ;
}
int mid=l+r>>1;
if(pos<=mid) s[y].rs=s[x].rs,insert(s[x].ls,s[y].ls,l,mid,pos);
else s[y].ls=s[x].ls,insert(s[x].rs,s[y].rs,mid+1,r,pos);
pushup(y);
}
bool cmp(node a,node b)
{
return a.num<b.num;
}
int qs(int l,int r,int x,int a,int b)
{
if(a>b) return 0;
if(a<=l&&r<=b) return s[x].sum;
int mid=l+r>>1;
if(b<=mid) return qs(l,mid,s[x].ls,a,b);
if(a>mid) return qs(mid+1,r,s[x].rs,a,b);
return qs(l,mid,s[x].ls,a,b)+qs(mid+1,r,s[x].rs,a,b);
}
int ql(int l,int r,int x,int a,int b)
{
if(a>b) return 0;
if(a<=l&&r<=b) return s[x].rm;
int mid=l+r>>1;
if(b<=mid) return ql(l,mid,s[x].ls,a,b);
if(a>mid) return ql(mid+1,r,s[x].rs,a,b);
return max(ql(l,mid,s[x].ls,a,b)+qs(mid+1,r,s[x].rs,a,b),ql(mid+1,r,s[x].rs,a,b));
}
int qr(int l,int r,int x,int a,int b)
{
if(a>b) return 0;
if(a<=l&&r<=b) return s[x].lm;
int mid=l+r>>1;
if(b<=mid) return qr(l,mid,s[x].ls,a,b);
if(a>mid) return qr(mid+1,r,s[x].rs,a,b);
return max(qr(mid+1,r,s[x].rs,a,b)+qs(l,mid,s[x].ls,a,b),qr(l,mid,s[x].ls,a,b));
}
int solve(int sta)
{
int a=ql(1,n,rt[sta-1],q[0],q[1]-1);
int b=qs(1,n,rt[sta-1],q[1],q[2]);
int c=qr(1,n,rt[sta-1],q[2]+1,q[3]);
if(a+b+c>=0) return 1;
return 0;
}
int main()
{
n=rd();
int i,j,l,r,mid;
for(i=1;i<=n;i++) p[i].num=rd(),p[i].org=i,maxx=max(maxx,p[i].num),minn=min(minn,p[i].num);
build(1,n,rt[0]);
sort(p+1,p+n+1,cmp);
for(i=1;i<=n;i++) insert(rt[i-1],rt[i],1,n,p[i].org);
m=rd();
for(i=1;i<=m;i++)
{
for(j=0;j<4;j++) q[j]=(rd()+ans)%n+1;
sort(q+0,q+4);
l=1,r=n+1;
while(l<r)
{
mid=l+r>>1;
if(solve(mid)) l=mid+1;
else r=mid;
}
ans=p[l-1].num;
printf("%d\n",ans);
}
return 0;
}

【BZOJ2653】middle 二分+可持久化线段树的更多相关文章

  1. BZOJ 4556(后缀数组+主席树求前驱后继+二分||后缀数组+二分+可持久化线段树)

    换markdown写了.. 题意: 给你一个1e5的字符串,1e5组询问,求\([l_1,r_1]\)的所有子串与\([l_2,r_2]\)的lcp 思路: 首先可以发现答案是具有单调性的,我们考虑二 ...

  2. 【XSY2720】区间第k小 整体二分 可持久化线段树

    题目描述 给你你个序列,每次求区间第\(k\)小的数. 本题中,如果一个数在询问区间中出现了超过\(w\)次,那么就把这个数视为\(n\). 强制在线. \(n\leq 100000,a_i<n ...

  3. bzoj 2653 middle (可持久化线段树)

    middle Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1981  Solved: 1097[Submit][Status][Discuss] D ...

  4. 【BZOJ-2653】middle 可持久化线段树 + 二分

    2653: middle Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1298  Solved: 734[Submit][Status][Discu ...

  5. [BZOJ 2653] middle(可持久化线段树+二分答案)

    [BZOJ 2653] middle(可持久化线段树+二分答案) 题面 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序 ...

  6. BZOJ.2653.[国家集训队]middle(可持久化线段树 二分)

    BZOJ 洛谷 求中位数除了\(sort\)还有什么方法?二分一个数\(x\),把\(<x\)的数全设成\(-1\),\(\geq x\)的数设成\(1\),判断序列和是否非负. 对于询问\(( ...

  7. 【bzoj2653】middle 可持久化线段树区间合并

    题目描述 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个长度为n的序列s.回答Q个这样的询问:s的左端点在[a,b]之间,右端点在[ ...

  8. 洛谷P3994 Highway(树形DP+斜率优化+可持久化线段树/二分)

    有点类似NOI2014购票 首先有方程$f(i)=min\{f(j)+(dep_i-dep_j)*p_i+q_i\}$ 这个显然是可以斜率优化的... $\frac {f(j)-f(k)}{dep_j ...

  9. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

随机推荐

  1. node.js零基础详细教程(6):mongodb数据库操作 以及导入导出

    第六章 建议学习时间4小时  课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑. ...

  2. jquery为动态添加元素绑定点击事件

    on()方法添加的事件处理程序适用于当前及未来的元素(比如由脚本创建的新元素) $("#mainbody").on("click",".link&qu ...

  3. C#通过SFTP协议操作文件

    本文主要是C#调用SSH实现文件上传下载功能,主要是要引用第三方类库Tamir.SharpSSH.dll. 以下是SFTPHelper类,实现了对文件的操作,可供参考. public class SF ...

  4. c# 中的UserControl是什么 用户控件和自定义控件有什么区别

    用户控件是许多控件的集成 自定义控件是自己写一个控件类,或者继承已有的控件类 复合控件是封装在公共容器内的 Windows 窗体控件的集合.这种控件有时称为“用户控件”.包含的控件称为“构成控件”. ...

  5. 使用command对象添加删除查询记录

    private void button1_Click(object sender, EventArgs e) { //实例化数据库连接对象 SqlConnection sqlcon = new Sql ...

  6. Ehcache2 的配置(不使用配置文件)

    EhCache是一个开放源码的,基于标准的高速缓存系统. 网上关于EhCache的使用配置很多,但是一般是基于配置文件的.但是实际应用中.我们可能需要动态的管理缓存,这时候单纯配置文件就不够用了. 所 ...

  7. java模拟从http上下载文件

    1.依赖 Apache httpclient 包. 2.代码 HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = ...

  8. Linux压缩解压缩命令学习笔记

    Linux中主要的压缩文件有:*.gz   *.tar  *.tar.gz  *.zip  *.bz2  *.tar.bz2 .zip这种古老的压缩格式,在window和Linux中都不需要安装软件可 ...

  9. Nginx+PHP-FPM优化技巧总结

    php-fpm的安装很简单,参见PHP(PHP-FPM)手动编译安装.下面主要讨论下如何提高Nginx+Php-fpm的性能.   1.Unix域Socket通信   之前简单介绍过Unix Doma ...

  10. hdu6005 Pandaland 想法+dijkstra

    /** 题目:hdu6005 Pandaland 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6005 题意:给定一个带权无向图,求权值和最小的环的值,如 ...