bzoj 2653 二分答案+可持久化线段树
首先离散化,然后我们知道如果对于一个询问的区间[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 二分答案+可持久化线段树的更多相关文章
- BZOJ2653middle——二分答案+可持久化线段树
题目描述 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个 长度为n的序列s.回答Q个这样的询问:s的左端点在[a,b]之间,右端点在 ...
- BZOJ 2653 middle 二分答案+可持久化线段树
题目大意:有一个序列,包含多次询问.询问区间左右端点在规定区间里移动所得到的最大中位数的值. 考虑对于每个询问,如何得到最优区间?枚举显然是超时的,只能考虑二分. 中位数的定义是在一个序列中,比中位数 ...
- bzoj 2653 middle (可持久化线段树)
middle Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1981 Solved: 1097[Submit][Status][Discuss] D ...
- BZOJ 3542 [Poi2014]Couriers ——可持久化线段树
[题目分析] 查找区间内出现次数大于一半的数字. 直接用主席树,线段树上维护区间大小,由于要求出现次数大于一半,每到一个节点可以分治下去. 时间复杂度(N+Q)logN [代码] #include & ...
- [BZOJ 2653] middle(可持久化线段树+二分答案)
[BZOJ 2653] middle(可持久化线段树+二分答案) 题面 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序 ...
- BZOJ.2653.[国家集训队]middle(可持久化线段树 二分)
BZOJ 洛谷 求中位数除了\(sort\)还有什么方法?二分一个数\(x\),把\(<x\)的数全设成\(-1\),\(\geq x\)的数设成\(1\),判断序列和是否非负. 对于询问\(( ...
- BZOJ 4556(后缀数组+主席树求前驱后继+二分||后缀数组+二分+可持久化线段树)
换markdown写了.. 题意: 给你一个1e5的字符串,1e5组询问,求\([l_1,r_1]\)的所有子串与\([l_2,r_2]\)的lcp 思路: 首先可以发现答案是具有单调性的,我们考虑二 ...
- BZOJ 2653 middle (可持久化线段树+中位数+线段树维护最大子序和)
题意: 左端点在[a,b],右端点在[c,d],求这个线段里中位数(上取整)最大值 思路: 对数组离散化,对每一个值建中位数的可持久化线段树(有重复也没事),就是对于root[i],大于等于i的值为1 ...
- 【BZOJ-2653】middle 可持久化线段树 + 二分
2653: middle Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1298 Solved: 734[Submit][Status][Discu ...
随机推荐
- linux应用自启动配置
Linux在启动时,会自动执行/etc/rc.d目录下的初始化程序,因此我们可以把启动任务放到该目录下: 1.因为其中的rc.local是在完成所有初始化之后执行,因此可以把启动脚本写到里面: 2.用 ...
- cli 中php的配置和phpinfo不一样
这是因为加载的php.ini的路径不一样 可以通过查看 php -i | grep php.ini 来确定两个加载的配置路径是一样的 win中没有grep的命令,可以把php -i 的内容重定向输出到 ...
- linux mysql表名大小写
1.用ROOT登录,修改/etc/my.cnf 2.在[mysqld]下加入一行:lower_case_table_names=1 0:区分大小写,1:不区分大小写 3.重新启动数据库即可
- 如何在java中实现跨线程的通讯
一般而言,如果没有干预的话,线程在启动之后会一直运行到结束,但有时候我们又需要很多线程来共同完成一个任务,这就牵扯到线程间的通讯. 如何让两个线程先后执行?Thread.join方法 private ...
- 双主双写、只备份某些表且要在建表ID自增
先展示下最终实现的配置 主1的配置(重要的,其他略) log-bin = mysql-bin #必须要有binlog auto_increment_offset = 1 #自增ID的初始值 auto_ ...
- 第163天:js面向对象-对象创建方式总结
面向对象-对象创建方式总结 1. 创建对象的方式,json方式 推荐使用的场合: 作为函数的参数,临时只用一次的场景.比如设置函数原型对象. var obj = {}; //对象有自己的 属性 和 行 ...
- 【BZOJ3203】保护出题人(动态规划,斜率优化)
[BZOJ3203]保护出题人(动态规划,斜率优化) 题面 BZOJ 洛谷 题解 在最优情况下,肯定是存在某只僵尸在到达重点的那一瞬间将其打死 我们现在知道了每只僵尸到达终点的时间,因为僵尸要依次打死 ...
- python基础----__slots__方法、__call__方法
''' 1.__slots__是什么:是一个类变量,变量值可以是列表,元祖,或者可迭代对象,也可以是一个字符串(意味着所有实例只有一个数据属性) 2.引子:使用点来访问属性本质就是在访问类或者对象的_ ...
- 如何在 ASP.NET 应用程序中实现模拟用户身份(在ASP.NET中以管理员身份运行网站)
前言 在实际的项目开发中,我们可能会需要调用一些非托管程序,而有些非托管程序需要有更高的身份权限才能正确执行.本文介绍了如何让IIS承载的ASP.NET网站以特定的账户执行,比如Administrat ...
- Myeclipse下更改所有jsp、html文件的编码
windows-->>preferences-->>gengral-->>