首先离散化,然后我们知道如果对于一个询问的区间[l1,r1],[l2,r2],我们二分到一个答案x,将[l1,r2]区间中的元素大于等于x的设为1,其余的设为-1,那么如果[l1,r1]的最大右区间和加上[r1,l2]的区间和加上[l2,r2]的最大左区间和大于等于0,那么最大的中位数一定大于等于x。因为这个区间中大于等于x的数量超过了一半,那么我们可以二分答案,然后判断最大的合法(见上文)区间和是否大于等于0。

  那么对于每个我们二分的值的区间-1,1情况我们不能建立n颗线段树,我们可以建立可持久化线段树来维护这个,最开始的初始值都为1,设rot[x]为二分的值为x的时候区间的1,-1情况的线段树,可以由rot[x-1]这颗线段树继承过来。

  反思:之前写的可持久化线段树都是建立的权值线段树,这次是用线段树维护区间值的,而且之前对于rot[x]只会有一次插入,这道题的rot[x]可能会有多次插入,在这里纠结了半天。还有我就是最后输出的是adr[ans],但是前面强制在线的时候我加的是ans,忘了改了= =。

/**************************************************************
Problem: 2653
User: BLADEVIL
Language: C++
Result: Accepted
Time:2012 ms
Memory:18196 kb
****************************************************************/ //By BLADEVIL
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 50010 using namespace std; struct rec {
int key,ans,num;
rec() {
key=ans=num=;
}
}a[maxn]; struct segment {
int left,right,maxr,maxl,sum;
int son[];
segment() {
left=right=maxr=maxl=sum=;
memset(son,,sizeof son);
}
}t[*maxn]; int n,m,tot;
int rot[maxn],adr[maxn]; bool cmp1(rec x,rec y) {
return x.ans<y.ans;
} bool cmp2(rec x,rec y) {
return x.num<y.num;
} void update(int x) {
t[x].sum=t[t[x].son[]].sum+t[t[x].son[]].sum;
t[x].maxl=max(t[t[x].son[]].sum+t[t[x].son[]].maxl,t[t[x].son[]].maxl);
t[x].maxr=max(t[t[x].son[]].sum+t[t[x].son[]].maxr,t[t[x].son[]].maxr);
} void build(int &x,int l,int r) {
if (!x) x=++tot;
t[x].left=l; t[x].right=r;
if (l==r) {
t[x].sum=t[x].maxl=t[x].maxr=;
return ;
}
int mid=t[x].left+t[x].right>>;
build(t[x].son[],l,mid); build(t[x].son[],mid+,r);
update(x);
} void insert(int &x,int rot,int y) {
if (!x) x=++tot;
t[x].left=t[rot].left; t[x].right=t[rot].right;
if (t[x].left==t[x].right) {
t[x].sum=t[x].maxl=t[x].maxr=-;
return ;
}
int mid=t[x].left+t[x].right>>;
if (y>mid) {
if (!t[x].son[]) t[x].son[]=t[rot].son[];
if (t[x].son[]==t[rot].son[]) t[x].son[]=;
insert(t[x].son[],t[rot].son[],y);
} else {
if (!t[x].son[]) t[x].son[]=t[rot].son[];
if (t[x].son[]==t[rot].son[]) t[x].son[]=;
insert(t[x].son[],t[rot].son[],y);
}
update(x);
} segment combine(segment x,segment y) {
segment ans;
ans.sum=x.sum+y.sum;
ans.maxl=max(x.sum+y.maxl,x.maxl);
ans.maxr=max(y.sum+x.maxr,y.maxr);
return ans;
} segment query(int x,int l,int r) {
if ((t[x].left==l)&&(t[x].right==r)) return t[x];
int mid=t[x].left+t[x].right>>;
if (l>mid) return query(t[x].son[],l,r); else
if (r<=mid) return query(t[x].son[],l,r); else
return combine(query(t[x].son[],l,mid),query(t[x].son[],mid+,r));
} int main(){
scanf("%d",&n);
for (int i=;i<=n;i++) scanf("%d",&a[a[i].num=i].ans);
sort(a+,a++n,cmp1);
int sum=,cur=a[].ans; adr[]=a[].ans;
for (int i=;i<=n;i++) if (a[i].ans==cur) a[i].key=sum; else a[i].key=++sum,adr[sum]=cur=a[i].ans;
//sort(a+1,a+1+n,cmp2);
//for (int i=1;i<=n;i++) printf("%d ",a[i].key); printf("\n");
build(rot[],,n);
for (int i=;i<=n;i++) insert(rot[a[i].key],rot[a[i].key-],a[i].num);
//for (int i=1;i<=tot;i++) printf("%d %d %d %d %d %d %d\n",i,t[i].left,t[i].right,t[i].son[0],t[i].son[1],t[i].maxl,t[i].maxr);
//for (int i=1;i<=n;i++) printf("%d ",adr[i]); printf("\n");
scanf("%d",&m);
int ans=;
while (m--) {
int ask[]; for (int i=;i<=;i++) scanf("%d",&ask[i]);
for (int i=;i<=;i++) ask[i]=(ask[i]+adr[ans])%n+;
ans=;
sort(ask+,ask+);
int l=,r=n;
while (l<=r) {
int mid=l+r>>,TOT=;
//printf("%d %d %d\n",l,r,a[mid].key);
//printf("%d %d\n",l,r);
segment a1=query(rot[a[mid].key-],ask[],ask[]),a2=query(rot[a[mid].key-],ask[],ask[]);
if (ask[]+<=ask[]-) TOT=query(rot[a[mid].key-],ask[]+,ask[]-).sum;
//printf("%d\n",TOT);
TOT+=a1.maxr+a2.maxl; //printf("%d\n",TOT);
//printf("%d\n",a1.maxr);
if (TOT>=) ans=a[mid].key,l=mid+; else r=mid-;
}
printf("%d\n",adr[ans]);
}
return ;
}

bzoj 2653 二分答案+可持久化线段树的更多相关文章

  1. BZOJ2653middle——二分答案+可持久化线段树

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

  2. BZOJ 2653 middle 二分答案+可持久化线段树

    题目大意:有一个序列,包含多次询问.询问区间左右端点在规定区间里移动所得到的最大中位数的值. 考虑对于每个询问,如何得到最优区间?枚举显然是超时的,只能考虑二分. 中位数的定义是在一个序列中,比中位数 ...

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

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

  4. BZOJ 3542 [Poi2014]Couriers ——可持久化线段树

    [题目分析] 查找区间内出现次数大于一半的数字. 直接用主席树,线段树上维护区间大小,由于要求出现次数大于一半,每到一个节点可以分治下去. 时间复杂度(N+Q)logN [代码] #include & ...

  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. BZOJ 4556(后缀数组+主席树求前驱后继+二分||后缀数组+二分+可持久化线段树)

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

  8. BZOJ 2653 middle (可持久化线段树+中位数+线段树维护最大子序和)

    题意: 左端点在[a,b],右端点在[c,d],求这个线段里中位数(上取整)最大值 思路: 对数组离散化,对每一个值建中位数的可持久化线段树(有重复也没事),就是对于root[i],大于等于i的值为1 ...

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

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

随机推荐

  1. JS在当前页面插入<script>标签,并执行

    将<script>标签绑定到<html>上, html可换成body,header等其他存在的标签. var htmm =document.getElementsByTagNa ...

  2. PHP中类型约束

    类型约束 什么叫类型约束? 就是要求某个变量只能使用(接收,存储)某种指定的数据类型: php属于“弱类型语言”,通常不支持类型约束: 相应的,强类型语言,类型约束却是其“基本特征”. php中,只支 ...

  3. javascript+html5+css3下拉刷新 数据效果

    文章摘自:suchso.com/projecteactual/javascript-html5-css3-taobao-xiala-data.html segmentfault.com/a/11900 ...

  4. innerHTML与innerText的区别: 前者获取的是dom对象内的所有html元素 后者获取的是dom对象里面的纯文本元素

  5. BZOJ 3626 LCA(离线+树链剖分)

    首先注意到这样一个事实. 树上两个点(u,v)的LCA的深度,可以转化为先将u到根路径点权都加1,然后求v到根路径上的总点权值. 并且该题支持离线.那么我们可以把一个区间询问拆成两个前缀和形式的询问. ...

  6. 【bzoj4425】[Nwerc2015]Assigning Workstations分配工作站 贪心+堆

    题目描述 佩内洛普是新建立的超级计算机的管理员中的一员. 她的工作是分配工作站给到这里来运行他们的计算研究任务的研究人员. 佩内洛普非常懒惰,不喜欢为到达的研究者们解锁机器. 她可以从在她的办公桌远程 ...

  7. 【BZOJ3244】【NOI2013】树的计数(神仙题)

    [BZOJ3244][NOI2013]树的计数(神仙题) 题面 BZOJ 这题有点假,\(bzoj\)上如果要交的话请输出\(ans-0.001,ans,ans+0.001\) 题解 数的形态和编号没 ...

  8. CF891E [数学题]

    1.答案=初始乘积-最终乘积的期望.然后直接dp+ntt是O(nklogk) 2.考虑展开式子ans=sum(a[i]-b[i]),大概感受一下未知数个数相同的项系数相同,问题在于如何求系数 3.没思 ...

  9. K Closest Numbers In Sorted Array

    Given a target number, a non-negative integer k and an integer array A sorted in ascending order, fi ...

  10. ajax方式提交文件到后台同时加其他参数

    struts2后台Action方法,直接用参数成员变量对象的属性接收即可