思路:首先容易想到二分答案,但如何去check呢,对于一段区间[l,r],把所有小于答案的都赋值为-1,大于等于它的都赋值为1,然后求左端点在[a,b],右端点在[c,d]的最大子串和即可(也就是区间[a,b]的最大右子串和加上(b,c)的子串和加上区间[c,d]的最大左子串和)这样既可,用个线段树维护一下,每次暴力重建,单次询问的复杂度是完全可以承受的,但如果多次询问时间复杂度将是n^2logn,复杂度将会爆炸,因此不能每次都暴力重建,然而能作为答案的只有n个元素,也就是说线段树只可能有n种形态,不妨利用可持久化线段树先预处理出询问a[i]时的线段树的形态,这样复杂度就能少一个n,也就是nlogn的复杂度是完全可以通过本题的。至于怎么预处理,先排序,然后在预处理以a[i]为答案的线段树时显然a[i-1]是要小于a[i]的,于是就在前一棵树的基础上把a[i-1]位置上的数改为-1,新建一个root即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define maxn 20005 int n,q,ans;
int t[4],a[maxn]; struct node{
int val,pos;
bool operator <(const node &a)const{return val<a.val;}
}v[maxn];
bool cmp(node a,node b){return a.pos<b.pos;} int read(){
int x=0;int f=1;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
return x*f;
} struct functional_segment_tree{
int treedeg,root[maxn];
struct treenode{
int sum,lmax,rmax,ls,rs;
treenode(){}
treenode(int a,int b,int c,int d,int e){sum=a,lmax=b,rmax=c,ls=d,rs=e;}
}tree[20*maxn];
treenode merge(treenode a,treenode b){
treenode ans=treenode(0,0,0,0,0);
ans.sum=a.sum+b.sum;
ans.lmax=max(a.lmax,a.sum+b.lmax);
ans.rmax=max(b.rmax,b.sum+a.rmax);
return ans;
}
void update(int p){
int ls=tree[p].ls,rs=tree[p].rs;
tree[p]=merge(tree[ls],tree[rs]);
tree[p].ls=ls,tree[p].rs=rs;
}
void build(int &p,int l,int r,int val){
p=++treedeg;int mid=(l+r)>>1;
if (l==r){tree[p].lmax=tree[p].rmax=tree[p].sum=val;return;}
build(tree[p].ls,l,mid,val),build(tree[p].rs,mid+1,r,val);
update(p);
}
void change(int k,int &p,int l,int r,int pos,int val){
p=++treedeg;
if (l==r){tree[p].lmax=tree[p].rmax=tree[p].sum=val;return;}
int mid=(l+r)>>1;
if (pos<=mid) tree[p].rs=tree[k].rs,change(tree[k].ls,tree[p].ls,l,mid,pos,val);
else tree[p].ls=tree[k].ls,change(tree[k].rs,tree[p].rs,mid+1,r,pos,val);
update(p);
}
treenode query(int p,int l,int r,int x,int y){
if (y<x) return treenode(0,0,0,0,0);
if (x<=l&&r<=y) return tree[p];
int mid=(l+r)>>1;treenode ans=treenode(0,0,0,0,0);bool flag=0;
if (x<=mid) ans=query(tree[p].ls,l,mid,x,y),flag=1;
if (y>mid){
if (flag) ans=merge(ans,query(tree[p].rs,mid+1,r,x,y));
else ans=query(tree[p].rs,mid+1,r,x,y);
}
return ans;
}
}T; bool check(int x){
int a=T.query(T.root[x],0,n-1,t[0],t[1]).rmax;
int b=T.query(T.root[x],0,n-1,t[1]+1,t[2]-1).sum;
int c=T.query(T.root[x],0,n-1,t[2],t[3]).lmax;
return a+b+c>=0;
} int main(){
n=read();
for (int i=0;i<n;i++) a[i]=read(),v[i].val=a[i],v[i].pos=i;
sort(v,v+n),T.build(T.root[0],0,n-1,1);
for (int i=1;i<n;i++) T.change(T.root[i-1],T.root[i],0,n-1,v[i-1].pos,-1);
q=read();
while (q--){
for (int i=0;i<4;i++) t[i]=(read()+ans)%n;sort(t,t+4);
int l=0,r=n-1;
while (l<r){
int mid=(l+r)>>1;
if (check(mid+1)) l=mid+1;
else r=mid;
}
printf("%d\n",ans=v[l].val);
}
return 0;
}

bzoj2653:middle的更多相关文章

  1. BZOJ2653:middle——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2653 Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2], ...

  2. 【BZOJ2653】Middle(主席树)

    [BZOJ2653]Middle(主席树) 题面 BZOJ 洛谷 Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你 ...

  3. 【BZOJ2653】middle 二分+可持久化线段树

    [BZOJ2653]middle Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个 长度为n的序列s.回答Q个 ...

  4. 垂直居中小记 line-height table vertical-align:middle

    垂直居中分两种情况:1.父元素高度确定的单行文本        2.以及父元素高度确定的多行文本. 1.垂直居中-父元素高度确定的单行文本的竖直居中的方法是通过设置父元素的 height 和 line ...

  5. ie7 下 float换行问题与vertical-align:middle; 失效问题

    声明:web小白的笔记,欢迎大神指点!联系QQ:1522025433. ie7 下 float换行问题 请直接看代码中和代码中的注释: <!doctype html> <html&g ...

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

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

  7. 去除img下方的空白(vertical-align:middle)——原理

    代码如下:一个简单的div装在一个img中, 然而在预览时却发现这种情况 也就是说img下方会无缘无故出现一个空隙.然后你发现,只要给img元素加上一个属性 vertical-align:middle ...

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

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

  9. 【BZOJ2653】middle(主席树,二分)

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

随机推荐

  1. Codeforces335B - Palindrome(区间DP)

    题目大意 给定一个长度不超过5*10^4的只包含小写字母的字符串,要求你求它的回文子序列,如果存在长度为100的回文子序列,那么只要输出长度为一百的回文子序列即可,否则输出它的最长回文子序列 题解 这 ...

  2. openstack 制作大于2TB根分区自动扩容的CENTOS镜像

    制作镜像的时候默认分的是30G空间 qemu-img create -f raw centos.img 30G 看官网文档安装完系统需要安装cloud-init和clout-utils包,本人安装了完 ...

  3. 问题.NET访问 IIS 元数据库失败。

    问题现象:访问 IIS 元数据库失败. 说明:执行当前 Web 请求期间,出现未处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息. 异常详细信息: System.We ...

  4. 49. Sort Letters by Case

    最后更新 一刷 还是Partition,只不过这次是按照大小写字母来. public class Solution { public void sortLetters(char[] chars) { ...

  5. Selenium 进行web自动化测试

    1.安装火狐版本时注意,如果无法正常安装,应该点击右键---以管理员身份运行 2.安装成功后,选择工具--选项--高级--更新,停止其自动化更新 3.maven里面加载应有的selenium的组件

  6. Cocos2d-x学习笔记之Cocos2d-x开发环境搭建

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Cocos2d-x源码包下载地址: http://cocos2d-x.org/projects/cocos2d-x/ ...

  7. cocos2d-x 卡牌翻牌效果的实现

    转自:http://blog.csdn.net/yanghuiliu/article/details/9115833 这个能实现翻牌的action就是CCOrbitCamera. static CCO ...

  8. 雄踞AppStore榜首的游戏&lt;别踩到白块儿&gt;源码分析和下载(一)

    AppStore和Android市场情况 莫名其妙爆红的游戏 真的莫名其妙,笔者下这个游戏两次.第一次在豌豆荚排行榜看到这款游戏,名字怪怪的,下载下来尝试一下,没认为有什么新颖的,还在思虑这是不是刷榜 ...

  9. 职责链模式vs状态模式区别

    状态模式在具体状态里设置了下一状态. 而职责链模式是在客户端代码里设置了下一状态的处理对象. 如果状态模式里的任何一环缺失,将导致事情无法进行下去.职责链模式的链式在客户端连接的,也就是说,如果我们请 ...

  10. Windows系统下的adb 配置

    1.将附件中的adb_tools.rar文件下载到电脑上,并解压.(注意:其路径尽量避免带有中文字符) 2.右键点击“计算机”->“属性”->“高级系统设置”->“高级”->“ ...