BZOJ 2653 middle (可持久化线段树+中位数+线段树维护最大子序和)
题意:
左端点在[a,b],右端点在[c,d],求这个线段里中位数(上取整)最大值
思路:
对数组离散化,对每一个值建中位数的可持久化线段树(有重复也没事),就是对于root[i],大于等于i的值为1,小于的为-1,
从小到大插入可持久化线段树即可
如果中位数为m,那么从左端点到右端点[l,r]的序列和应该>=0,我们只需要二分这个m检查是不是序列和>=0即可
满足左端点在[a,b],右端点在[c,d]的子序列和的最大值,就是我们在用线段树维护最大子序和时的
[b+1,c-1]的sum+[a,b]的maxr+[c,d]的maxl
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional> #define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
//#define lc root<<1
//#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL; const db eps = 1e-;
const int mod = 1e9+;
const int maxn = 2e5+;
const int maxm = 2e6+;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0); int n;
PI a[maxn];
int q;
vector<ll>v;
int getid(ll x){
return lower_bound(v.begin(), v.end(), x)-v.begin()+;
}
bool cmp(PI a, PI b){
if(a.fst==b.fst)return a.sc<b.sc;
return a.fst<b.fst;
}
int root[maxn];
struct Node{
int maxl,maxr;
int sum;
}node[maxn*];
int ls[maxn],rs[maxn];
int tot,totn;
void build(int l, int r, int &root){
root = ++tot;
int mid = (l+r)>>;
if(l==r){
node[root].maxl=node[root].maxr=node[root].sum=;
return;
}
build(l, mid, ls[root]);
build(mid+, r, rs[root]);
node[root].maxl=max(node[ls[root]].sum+node[rs[root]].maxl, node[ls[root]].maxl);
node[root].maxr=max(node[rs[root]].sum+node[ls[root]].maxr, node[rs[root]].maxr);
node[root].sum=node[ls[root]].sum+node[rs[root]].sum;
return;
}
void insert(int lst, int &now, int l, int r, int p){
now = ++tot;
ls[now]=ls[lst];
rs[now]=rs[lst];
node[now] = node[lst];
int mid = (l+r)>>;
if(l==r){
node[now].maxl=node[now].maxr=node[now].sum=-;
return;
}
if(p<=mid)insert(ls[lst], ls[now], l, mid, p);
else insert(rs[lst], rs[now], mid+, r, p);
node[now].maxl=max(node[ls[now]].sum+node[rs[now]].maxl, node[ls[now]].maxl);
node[now].maxr=max(node[rs[now]].sum+node[ls[now]].maxr, node[rs[now]].maxr);
node[now].sum=node[ls[now]].sum+node[rs[now]].sum;
}
Node query(int ql, int qr, int l, int r, int now){ int mid = (l+r)>>;
if(l==ql&&r==qr){
return node[now];
}
else if(mid>=qr){
return query(ql, qr, l, mid, ls[now]);
}
else if(mid<ql){
return query(ql, qr, mid+, r, rs[now]);
}
else{
Node ans;
Node lc=query(ql,mid,l,r,now);
Node rc=query(mid+,qr,l,r,now);
ans.sum=lc.sum+rc.sum;
ans.maxl=max(lc.sum+rc.maxl,lc.maxl);
ans.maxr=max(rc.sum+lc.maxr,rc.maxr);
return ans;
}
}
void dfs(int x){
printf("%d %d %d %d %d %d\n",x,ls[x],rs[x],node[x].sum,node[x].maxl,node[x].maxr);
if(ls[x])dfs(ls[x]);
if(rs[x])dfs(rs[x]);
}
int main() {
scanf("%d", &n);
for(int i = ; i <= n; i++){
scanf("%d" ,&a[i].fst);
a[i].sc=i;
v.pb(a[i].fst);
}
sort(v.begin(), v.end());
v.erase(unique(v.begin(),v.end()),v.end());
totn=v.size();
int lstans = ;
int tmp[];
sort(a+,a++n,cmp);
build(,n,root[]);
for(int i = ; i <= n; i++){
insert(root[i-],root[i],,n,a[i].sc);
}int q;
//dfs(root[4]);
scanf("%d", &q);
while(q--){
for(int i = ; i <= ; i++){
scanf("%d", &tmp[i]);
tmp[i]=(tmp[i]+lstans)%n;
}
sort(tmp+,tmp++);
int l = ;
int r = n+;
int ans = ; while(l<=r){
int mid = (l+r)>>;
int res=max(query(tmp[]+,tmp[]+-,,n,root[mid-]).maxr,);
res+=query(tmp[]+,tmp[]+,,n,root[mid-]).sum;
res+=max(query(tmp[]++,tmp[]+,,n,root[mid-]).maxl,);
if(res>=){
ans=mid;
l=mid+;
}
else r = mid-;
}
printf("%d\n",lstans=v[ans-]);
}
return ;
}
/*
5
2 4 1 5 3
3
3 1 0 2
2 3 1 4
3 1 4 0 5
170337785
271451044
22430280
969056313
206452321
3
3 1 0 2
2 3 1 4
3 1 4 0
*/
BZOJ 2653 middle (可持久化线段树+中位数+线段树维护最大子序和)的更多相关文章
- [BZOJ 2653] middle(可持久化线段树+二分答案)
[BZOJ 2653] middle(可持久化线段树+二分答案) 题面 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序 ...
- bzoj 2653: middle (主席树+二分)
2653: middle Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2522 Solved: 1434[Submit][Status][Disc ...
- BZOJ 2653: middle(主席树+二分答案)
传送门 解题思路 首先可以想到一种暴力做法,就是询问时二分,然后大于等于这个值的设为1,否则设为-1,然后就和GSS1那样统计答案.但是发现这样时间空间复杂度都很爆炸,所以考虑预处理,可以用主席树来做 ...
- bzoj 2653 middle (可持久化线段树)
middle Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1981 Solved: 1097[Submit][Status][Discuss] D ...
- BZOJ 2653 middle 二分答案+可持久化线段树
题目大意:有一个序列,包含多次询问.询问区间左右端点在规定区间里移动所得到的最大中位数的值. 考虑对于每个询问,如何得到最优区间?枚举显然是超时的,只能考虑二分. 中位数的定义是在一个序列中,比中位数 ...
- BZOJ 2653: middle [主席树 中位数]
传送门 题意: 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个 长度为n的序列s.回答Q个这样的询问:s的左端点在[a,b]之间,右 ...
- bzoj 2653 middle 二分答案 主席树判定
判断中位数是否可行需要将当前的解作为分界,大于其的置为1,小于为-1,然后b-c必选,ab,cd可不选,这个用线段树判定就好 但不能每次跑,所以套主席树,按权值排序,构建主席树,更新时将上一个节点改为 ...
- BZOJ 2653: middle 主席树 二分
https://www.lydsy.com/JudgeOnline/problem.php?id=2653 因为是两个方向向外延伸所以不能对编号取前缀和(这里只有前缀和向后传递的性质,不是实际意义的和 ...
- bzoj 2653 middle(主席树)
题面:https://vjudge.net/problem/HYSBZ-2653 博客:https://blog.csdn.net/litble/article/details/78984846 这个 ...
随机推荐
- LinkedHashMap与HashMap的使用比较
现在由于项目需要,使用了LinkedHashMap,一开始由于很少用到Map,然后就直接使用了HashMap,在将数据成功存入之后取出来就出了问题,数据输出顺序没有按预期顺序输出,现在先看代码: 文件 ...
- Mybatis Plugin 以及Druid Filer 改写SQL
背景 工作中偶尔会碰到需要统一修改SQL的情况,例如有以下表结构: CREATE TABLE `test_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, ` ...
- Docker——WIN7 安装 Docker实战与入门
1.Docker简介 Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目.它基于 Google 公司推出的 Go 语言实现. 项目后来加入了 Lin ...
- List去重问题与方法
面试中经常被问到的list如何去重,用来考察你对list数据结构,以及相关方法的掌握,体现你的java基础学的是否牢固.我们大家都知道,set集合的特点就是没有重复的元素.如果集合中的数据类型是基本数 ...
- pycharm 连接mysql失败
1.下载与之对应的驱动 2.更改数据库的时区(问题大多数出现在这里) .查看时区 show variables like '%time_zone%'; .设置时区 set global time_zo ...
- [bzoj1005] [洛谷P2624] 明明的烦恼
Description 自从明明学了树的结构,就对奇怪的树产生了兴趣-- 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为N(0 ...
- Tomcat 9 与JDK 8 的安装与配置
Tomcat 9的安装与配置 解压压缩包,我的解压路径是:D:\Program Files\Java 注意:这里tomcat压缩包不能解压到C盘,否则会因为C盘文件夹访问权限授权问题,没法解决后面出现 ...
- redis server can not continue
- ①CM+CDH6.2.0安装(全网最全)
CM+CDH6.2.0环境准备 一 虚拟机及CentOs7配置 CentOS下载地址 master(16g+80g+2cpu+2核)+2台slave(8g+60g+2cpu+2核) 1.1 打开&qu ...
- HTTP访问控制模块(HTTP Access)
·摘要这个模块提供简单的基于主机的访问控制.ngx_http_access_module这个模块可以详细的检查客户端IP,并且按顺序执行第一条匹配的规则.如下例: location / { deny ...