与中位数有关的题二分答案是很常用的trick。二分答案之后,将所有大于它的看成1小于它的看成-1,那么只需要判断是否存在满足要求的一段和不小于0。

  由于每个位置是1还是-1并不固定,似乎不是很好算。考虑暴力一点的想法:对于每一种答案预处理。这样查询就很好办了,线段树上每个区间维护最大前缀和后缀和及总和即可。并且可以发现按答案从小到大考虑的话每个位置都是开始一段为1之后为-1,总修改次数只有n次,建主席树即可。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 20010
int n,m,a[N],b[N],root[N],lastans,cnt=;
vector<int> p[N];
struct data{int l,r,sum,pre,suf;
}tree[N<<];
void build(int &k,int l,int r)
{
k=++cnt;tree[k].sum=tree[k].pre=tree[k].suf=r-l+;
if (l==r) return;
int mid=l+r>>;
build(tree[k].l,l,mid);
build(tree[k].r,mid+,r);
}
void modify(int &k,int l,int r,int x)
{
tree[++cnt]=tree[k];k=cnt;
tree[k].sum-=;
if (l==r) {tree[k].pre=tree[k].suf=-;return;}
int mid=l+r>>;
if (x<=mid) modify(tree[k].l,l,mid,x);
else modify(tree[k].r,mid+,r,x);
tree[k].pre=max(tree[tree[k].l].pre,tree[tree[k].l].sum+tree[tree[k].r].pre);
tree[k].suf=max(tree[tree[k].r].suf,tree[tree[k].r].sum+tree[tree[k].l].suf);
}
int querysum(int k,int l,int r,int x,int y)
{
if (x>y) return ;
if (l==x&&r==y) return tree[k].sum;
int mid=l+r>>;
if (y<=mid) return querysum(tree[k].l,l,mid,x,y);
else if (x>mid) return querysum(tree[k].r,mid+,r,x,y);
else return querysum(tree[k].l,l,mid,x,mid)+querysum(tree[k].r,mid+,r,mid+,y);
}
int querypre(int k,int l,int r,int x,int y)
{
if (l==x&&r==y) return tree[k].pre;
int mid=l+r>>;
if (y<=mid) return querypre(tree[k].l,l,mid,x,y);
else if (x>mid) return querypre(tree[k].r,mid+,r,x,y);
else return max(querypre(tree[k].l,l,mid,x,mid),querysum(tree[k].l,l,mid,x,mid)+querypre(tree[k].r,mid+,r,mid+,y));
}
int querysuf(int k,int l,int r,int x,int y)
{
if (l==x&&r==y) return tree[k].suf;
int mid=l+r>>;
if (y<=mid) return querysuf(tree[k].l,l,mid,x,y);
else if (x>mid) return querysuf(tree[k].r,mid+,r,x,y);
else return max(querysuf(tree[k].r,mid+,r,mid+,y),querysum(tree[k].r,mid+,r,mid+,y)+querysuf(tree[k].l,l,mid,x,mid));
}
int calc(int k,int a,int b,int c,int d)
{
return querysum(root[k],,n,b+,c-)+querysuf(root[k],,n,a,b)+querypre(root[k],,n,c,d);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj2653.in","r",stdin);
freopen("bzoj2653.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read();
for (int i=;i<=n;i++) b[i]=a[i]=read();
sort(b+,b+n+);
int t=unique(b+,b+n+)-b;
for (int i=;i<=n;i++)
{
a[i]=lower_bound(b+,b+t,a[i])-b;
p[a[i]].push_back(i);
}
build(root[],,n);
for (int i=;i<t;i++)
{
root[i]=root[i-];
for (int j=;j<p[i-].size();j++)
modify(root[i],,n,p[i-][j]);
}
m=read();
while (m--)
{
int q[]={(read()+lastans)%n,(read()+lastans)%n,(read()+lastans)%n,(read()+lastans)%n};
sort(q,q+);
int l=,r=t-,ans=;
while (l<=r)
{
int mid=l+r>>;
if (calc(mid,q[]+,q[]+,q[]+,q[]+)>=) ans=mid,l=mid+;
else r=mid-;
}
printf("%d\n",lastans=b[ans]);
}
return ;
}

BZOJ2653 middle(二分答案+主席树)的更多相关文章

  1. bzoj 2653 middle 二分答案 主席树判定

    判断中位数是否可行需要将当前的解作为分界,大于其的置为1,小于为-1,然后b-c必选,ab,cd可不选,这个用线段树判定就好 但不能每次跑,所以套主席树,按权值排序,构建主席树,更新时将上一个节点改为 ...

  2. BZOJ5343: [Ctsc2018]混合果汁 二分答案+主席树

    分析: 整体二分或二分答案+主席树,反正没有要求强制在线,两个都可以做... 贪心还是比较显然的,那么就是找前K大的和...和CQOI的任务查询系统很像 附上代码: #include <cstd ...

  3. BZOJ_5343_[Ctsc2018]混合果汁_二分答案+主席树

    BZOJ_5343_[Ctsc2018]混合果汁_二分答案+主席树 题意:给出每个果汁的价格p,美味度d,最多能放的体积l.定义果汁混合后的美味度为果汁的美味度的最小值. m次询问,要求花费不大于g, ...

  4. 2019杭电多校第四场hdu6621 K-th Closest Distance(二分答案+主席树)

    K-th Closest Distance 题目传送门 解题思路 二分答案+主席树 先建主席树,然后二分答案mid,在l和r的区间内查询[p-mid, p+mid]的范围内的数的个数,如果大于k则说明 ...

  5. BZOJ4556 [Tjoi2016&Heoi2016]字符串 SA ST表 二分答案 主席树

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ4556.html 题目传送门 - BZOJ4556 题意 给定一个长度为 $n$ 的字符串 $s$ . ...

  6. BZOJ1926[Sdoi2010]粟粟的书架——二分答案+主席树

    题目描述 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Co rmen 的文章.粟粟家中有一个 R行C 列的巨型书架,书架的每一个位 ...

  7. Codeforces Round #276 (Div. 1) E. Sign on Fence (二分答案 主席树 区间合并)

    链接:http://codeforces.com/contest/484/problem/E 题意: 给你n个数的,每个数代表高度: 再给出m个询问,每次询问[l,r]区间内连续w个数的最大的最小值: ...

  8. BZOJ 4556: [Tjoi2016&Heoi2016]字符串(后缀数组 + 二分答案 + 主席树 + ST表 or 后缀数组 + 暴力)

    题意 一个长为 \(n\) 的字符串 \(s\),和 \(m\) 个询问.每次询问有 \(4\) 个参数分别为 \(a,b,c,d\). 要你告诉它 \(s[a...b]\) 中的所有子串 和 \(s ...

  9. BZOJ3277 串(后缀数组+二分答案+主席树)

    因为不会SAM,考虑SA.将所有串连起来并加分隔符,每次考虑计算以某个位置开始的子串有多少个合法. 对此首先二分答案,找到名次数组上的一个区间,那么只需要统计有多少个所给串在该区间内出现就可以了.这是 ...

随机推荐

  1. golang 文件服务器

    在go语言中可以用一句代码做一个文件服务器.如果有很多文件需要通过网页来供其他人下载,可以使用这个方法. package main import ( "log" "net ...

  2. HBase启动时报错:/bin/java: No such file or directory6/bin/../bin/hbase: line 412: /usr/local/jdk1.8.0_152/bin/java

    今天在启动HBase时发现如下错误:/bin/java: No such file or directory6/bin/../bin/hbase: line 412: /usr/local/jdk1. ...

  3. GBDT源码剖析

    如今,GBDT被广泛运用于互联网行业,他的原理与优点这里就不细说了,网上google一大把.但是,我自认为自己不是一个理论牛人,对GBDT的理论理解之后也做不到从理论举一反三得到更深入的结果.但是学习 ...

  4. Redis学习之路(四)之Redis集群

    [toc] #Redis集群 1.Redis Cluster简介 Redis Cluster为Redis官方提供的一种分布式集群解决方案.它支持在线节点增加和减少. 集群中的节点角色可能是主,也可能是 ...

  5. Markdown打造高逼格博客

    这里首先假设读者你已经掌握了Markdown与GitHub的基本用法 如果不会, 请先自行百度或Google, 我目前还没写Markdown与GitHub的教程 看云只是一个推荐, 可以认为协助生成格 ...

  6. 程序员大佬推荐的java学习路线

    作为我的第一篇博客,我第一个想到的就是在校时就看到的这篇文章.并且在之后的时间里自己都反复观看过,有时候这不单单是一篇学习路线,也是审视自己技术能力的里程碑,和激励自己的鞭挞绳. 先来个书籍清单: & ...

  7. Codeforces Round #550 (Div. 3) E. Median String (模拟)

    Median String time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  8. web安全入门课程笔记——网站基础与信息搜集

    2-1 网站的基本概念 URL统一资源定位符 这是一个动态页面 ?ID 查询条件 后台数据库最有可能:ACCESS Web容器(web容器是一种服务程序,在服务器一个端口就有一个提供相应服务的程序,而 ...

  9. Celery基本使用

    Celery 什么是Celery? Celery是一种简单/高效/灵活的即插即用的分布式任务队列. Celery应用场景? 需要异步处理的任务,发邮件/发短信/上传等耗时的操作.最终到达提升用户体验的 ...

  10. PAT甲题题解-1051. Pop Sequence (25)-堆栈

    将1~n压入最多为m元素的栈 给出k个出栈序列,问你是否能够实现. 能输出YES 否则NO 模拟一遍即可,水题. #include <iostream> #include <cstd ...