BZOJ2653 middle(二分答案+主席树)
与中位数有关的题二分答案是很常用的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(二分答案+主席树)的更多相关文章
- bzoj 2653 middle 二分答案 主席树判定
判断中位数是否可行需要将当前的解作为分界,大于其的置为1,小于为-1,然后b-c必选,ab,cd可不选,这个用线段树判定就好 但不能每次跑,所以套主席树,按权值排序,构建主席树,更新时将上一个节点改为 ...
- BZOJ5343: [Ctsc2018]混合果汁 二分答案+主席树
分析: 整体二分或二分答案+主席树,反正没有要求强制在线,两个都可以做... 贪心还是比较显然的,那么就是找前K大的和...和CQOI的任务查询系统很像 附上代码: #include <cstd ...
- BZOJ_5343_[Ctsc2018]混合果汁_二分答案+主席树
BZOJ_5343_[Ctsc2018]混合果汁_二分答案+主席树 题意:给出每个果汁的价格p,美味度d,最多能放的体积l.定义果汁混合后的美味度为果汁的美味度的最小值. m次询问,要求花费不大于g, ...
- 2019杭电多校第四场hdu6621 K-th Closest Distance(二分答案+主席树)
K-th Closest Distance 题目传送门 解题思路 二分答案+主席树 先建主席树,然后二分答案mid,在l和r的区间内查询[p-mid, p+mid]的范围内的数的个数,如果大于k则说明 ...
- BZOJ4556 [Tjoi2016&Heoi2016]字符串 SA ST表 二分答案 主席树
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ4556.html 题目传送门 - BZOJ4556 题意 给定一个长度为 $n$ 的字符串 $s$ . ...
- BZOJ1926[Sdoi2010]粟粟的书架——二分答案+主席树
题目描述 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Co rmen 的文章.粟粟家中有一个 R行C 列的巨型书架,书架的每一个位 ...
- Codeforces Round #276 (Div. 1) E. Sign on Fence (二分答案 主席树 区间合并)
链接:http://codeforces.com/contest/484/problem/E 题意: 给你n个数的,每个数代表高度: 再给出m个询问,每次询问[l,r]区间内连续w个数的最大的最小值: ...
- BZOJ 4556: [Tjoi2016&Heoi2016]字符串(后缀数组 + 二分答案 + 主席树 + ST表 or 后缀数组 + 暴力)
题意 一个长为 \(n\) 的字符串 \(s\),和 \(m\) 个询问.每次询问有 \(4\) 个参数分别为 \(a,b,c,d\). 要你告诉它 \(s[a...b]\) 中的所有子串 和 \(s ...
- BZOJ3277 串(后缀数组+二分答案+主席树)
因为不会SAM,考虑SA.将所有串连起来并加分隔符,每次考虑计算以某个位置开始的子串有多少个合法. 对此首先二分答案,找到名次数组上的一个区间,那么只需要统计有多少个所给串在该区间内出现就可以了.这是 ...
随机推荐
- ZOJ3623:Battle Ships(全然背包)
Battle Ships is a new game which is similar to Star Craft. In this game, the enemy builds a defense ...
- Flutter - 添加从左向右滑动,返回上一个页面
很多App比如微信.IT之家等都支持从屏幕左侧向右滑动,来返回上一个页面. 很多iOS上的App也都支持. 那么这个神奇的手势滑动是怎么实现的呢? 其实非常简单,只需要添加一句话即可. platfor ...
- 20155308『网络对抗技术』Exp5 MSF基础应用
20155308『网络对抗技术』Exp5 MSF基础应用 一.原理与实践说明 实践内容 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要完成: 一个主动攻击实 ...
- 20155310 Exp6 信息收集与漏洞扫描
20155310 Exp6 信息收集与漏洞扫描 基础问题回答 1.哪些组织负责DNS,IP的管理. 顶级的管理者是Internet Corporation for Assigned Names and ...
- WPF编程,通过Double Animation动态旋转控件的一种方法。
原文:WPF编程,通过Double Animation动态旋转控件的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/art ...
- Luogu P1972 [SDOI2009]HH的项链
很清新自然凶猛的数据结构题,都是套路啊 我们可以考虑离线做,先把区间按右端点从小到大排序 首先注意到一种贝壳如果在一段中出现超过1次,那么它在前面或后面就无关紧要了 举一个例子: 对于数列1 2 3 ...
- 【Java框架型项目从入门到装逼】第十一节 用户新增之把数据传递到后台
让我们继续来做"主线任务",这一节,我们来做具体的用户新增功能.首先,为了简单起见,我把主页面改了一些,改的是列表那一块.删去了一些字段,和数据库表对应一致: 现在,我们要实现一个 ...
- pandas:根据行间差值进行数据合并
1. 问题描述 在处理用户上网数据时,用户的上网行为数据之间存在时间间隔,按照实际情况,若时间间隔小于阈值(next_access_time_app),则可把这几条上网行为合并为一条行为数据:若时间间 ...
- Gitlab+Jenkins学习之路(十四)之自动化脚本部署实践
目录 一.环境说明和准备 1.环境说明 2.服务器准备工作 二.发布脚本编写 1.自动化部署流程设计 2.自动化部署脚本编写 三.发布测试 1.开发机和github添加ssh信任 2.克隆项目到开发机 ...
- css怎样去掉多个Img标签之间的间隙
在写css的时候经常会遇到这样的情况,两张宽度加起来是2n的图片,在宽度为2n的容器中放不下,这是因为两张图片之间有一段间隙的缘故,产生这种现象的原因是浏览器把两个img标签之间的空格当成了空白节点. ...