传送门
写在前面:虽然这是一道我再也不想写的题目,但很好很有价值
思路:
cxlove大神:

要求中位数最大,首先二分中位数,然后判断可行不可行。
判断X可行不可行,对于区间内的数,凡是>=X的标为1,否则为-1。这样的话,求一次最大区间和 如果大于等于0,则说明可行。

这要求我们不能像之前那样建立权值线段树的主席树(区间即为权值)了,而是以权值为下标,维护区间[1,n]的信息,可能有点拗口,这里就理解是我们平常写的普通线段树好了,只是这里是n棵由于根的不同而信息不同的线段树
具体实现

对于题目要求,我们很容易维护[b+1,c-1]间的信息,即求得序列总和,而[a,b]的右起最大子序列和(必须包含右端点)与[c,d]左起最大子序列和(必须包含左端点)确实把我难了好久,唉……

一开始建树的时候每个位置都是1(原本所有位置的标记都是1)。序列按照从小到大顺序插入主席树。做第i棵树的时候,它第i-1大的数的位置上改为-1。什么意思呢,就是说,如果X取的是第i大的那个数,那么第i-1大的数的标记就要改为-1(更小的那些在做第i-1棵树的时候就已经改为-1了)。于是在询问X的时候是计算root[X]这棵线段树里面的各种值了。
最后是如何求[[a,b],[c,d]]区间的最大子段和。其实很简单,因为(b,c)这段是一定要取的,所以答案就是[a,b]的最大右连续和+(b,c)的区间和+[c,d]的最大左连续和。

注意:
离散化后的值,下标什么的好烦人啊!很容易搞混的说
代码:

#include<bits/stdc++.h>
#define M 20004
#define ls(x) a[x].ch[0]
#define rs(x) a[x].ch[1]
using namespace std;
int n,q,cnt,lastans;
int c[M],ID[M];
struct disc
{int data,id;bool operator <(const disc other)const{return data<other.data;}
}b[M];
struct Chairman_tree
{int sum_L,sum_R,sum,ch[2];
}a[M*33];
void pushup(int rt,int begin,int end)
{int mid=(begin+end)>>1;a[rt].sum=a[ls(rt)].sum+a[rs(rt)].sum;a[rt].sum_L=max(a[ls(rt)].sum_L,a[ls(rt)].sum+a[rs(rt)].sum_L);a[rt].sum_R=max(a[rs(rt)].sum_R,a[rs(rt)].sum+a[ls(rt)].sum_R);
}
void build(int rt,int begin,int end)
{if (begin==end) {a[rt]=(Chairman_tree){1,1,1,{0,0}};return;}int mid=(begin+end)>>1;ls(rt)=++cnt;rs(rt)=++cnt;build(ls(rt),begin,mid);build(rs(rt),mid+1,end);pushup(rt,begin,end);
}
void insert(int now,int L,int R,int rt,int pos,int val)
{if (L==R){a[rt]=(Chairman_tree){val,val,val,{0,0}};return;}int mid=(L+R)>>1;if (mid>=pos)rs(rt)=rs(now),ls(rt)=++cnt,insert(ls(now),L,mid,ls(rt),pos,val);elsels(rt)=ls(now),rs(rt)=++cnt,insert(rs(now),mid+1,R,rs(rt),pos,val);pushup(rt,L,R);
}
int get_sum(int rt,int begin,int end,int l,int r)
{if (l>r) return 0;if (l<=begin&&end<=r) return a[rt].sum;int mid=(begin+end)>>1,ans=0;if (mid>=l) ans+=get_sum(ls(rt),begin,mid,l,r);if (mid<r) ans+=get_sum(rs(rt),mid+1,end,l,r);return ans;
}
int get_L(int rt,int begin,int end,int l,int r)
{if (l<=begin&&end<=r) return a[rt].sum_L;int mid=(begin+end)>>1;if (mid>=r) return get_L(ls(rt),begin,mid,l,r);else if (mid<l) return get_L(rs(rt),mid+1,end,l,r);else return max(get_L(ls(rt),begin,mid,l,r),get_sum(ls(rt),begin,mid,l,r)+get_L(rs(rt),mid+1,end,l,r));
}
int get_R(int rt,int begin,int end,int l,int r)
{if (l<=begin&&end<=r) return a[rt].sum_R;int mid=(begin+end)>>1;if (mid>=r) return (0,get_R(ls(rt),begin,mid,l,r));else if (mid<l) return get_R(rs(rt),mid+1,end,l,r);else return max(get_R(rs(rt),mid+1,end,l,r),get_sum(rs(rt),mid+1,end,l,r)+get_R(ls(rt),begin,mid,l,r));
}
main()
{scanf("%d",&n);for (int i=1;i<=n;i++)scanf("%d",c+i),b[i].id=i,b[i].data=c[i];sort(b+1,b+n+1);for (int i=1;i<=n;i++)c[b[i].id]=i,ID[i]=b[i].data;cnt=n;build(1,1,n);for (int i=2;i<=n;i++) insert(i-1,1,n,i,b[i-1].id,-1);scanf("%d",&q);int p[4];while (q--){for (int i=0;i<4;i++)scanf("%d",p+i),p[i]=(p[i]+lastans)%n,p[i]++;sort(p,p+4);int l=1,r=n,mid;while(l<=r){mid=(l+r)>>1;if (get_sum(mid,1,n,p[1]+1,p[2]-1)+get_R(mid,1,n,p[0],p[1])+get_L(mid,1,n,p[2],p[3])>=0)l=mid+1,lastans=ID[mid];elser=mid-1;}printf("%d\n",lastans);}
}

【BZOJ2653】middle,主席树(非权值线段树)维护序列和信息+二分答案相关推荐

  1. 数据结构:树套树-替罪羊树套权值线段树

    BZOJ3065 本题是在BZOJ上的处女A,实在不应该拿这样一道题来开头 平衡树套线段树应该是树套树问题里比较难的一种了,当然我记得还有一个替罪羊树套Trie树的题,我是不信自己能写出来的. 外层的 ...

  2. Governing sand(权值线段树/主席树)

    链接:https://ac.nowcoder.com/acm/contest/887/C 来源:牛客网 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 65536K,其他语言13107 ...

  3. bzoj 1503 (权值线段树)

    由于蒟蒻实在是ttttttai 菜了,于是开始了学习主席树,权值线段树作为主席树的前置知识,于是蒟蒻各种百度百度,谷歌谷歌,抄网上的代码,然后终于A了这个题目.也还算是有一点收获. 题目:芝麻开门 题 ...

  4. 树套树 ----- P1975 [国家集训队]排队(树状数组套权值线段树求动态逆序对)

    解题思路: 首先我们知道交换两个数a[l]和a[r]a[l]和a[r]a[l]和a[r]影响到的区间是[l+1,r−1][l+1,r-1][l+1,r−1] 对于a[l]a[l]a[l],我们要减去[ ...

  5. 【BZOJ3295】动态逆序对,CDQ分治/BIT套权值线段树

    传送门 思路: 用来练习cdq的题目 断断续续纠结了2天 因为loli一直在考试 最后莫名乱搞了一发就A了? 实际上是考虑每一次修改对答案的贡献,即位置在1~x-1且大于x的数以及位置在x+1~n且小 ...

  6. 【BZOJ3110】【codevs1616】K大数查询,权值线段树套普通线段树

    Time:2016.05.09 Author:xiaoyimi 转载注明出处谢谢 传送门1 传送门2 思路: 之前没怎么接触过权值线段树(非主席树),这次就当学习了一下吧.一开始还把题意理解错了,我的 ...

  7. 【bzoj2770】YY的Treap 权值线段树

    题目描述 志向远大的YY小朋友在学完快速排序之后决定学习平衡树,左思右想再加上SY的教唆,YY决定学习Treap.友爱教教父SY如砍瓜切菜般教会了YY小朋友Treap(一种平衡树,通过对每个节点随机分 ...

  8. 树套树 ---- 树状数组套权值线段树模板题 P2617 Dynamic Rankings 动态第K大

    题目链接 题目大意: 给你一个数组aaa,aaa有两个操作 询问aaa中[l,r][l,r][l,r]区间里面第kkk小的数是哪个? 修改axa_xax​为yyy 解题思路: 首先我们知道权值线段树是 ...

  9. 权值线段树小结(hdu多校,普通平衡树,郁闷的出纳员)

    之前刷了一点主席树的题目,但是没有系统的做过权值线段树的题目.主席树是多根权值线段树的综合.权值线段树可以解决在总区间里求第k大的问题.在普通的线段树里,我们每一个节点维护的是权值大小.但是在权值线段 ...

最新文章

  1. memcached全面剖析–2.理解memcached的内存存储
  2. 哇哦!恍然大悟般的“share”功能的实现!
  3. 日报 18/06/04
  4. 小米redmi_安兔兔公布12月安卓手机性能榜:小米、Redmi领衔
  5. 编程挑战:字符串的完美度
  6. python 学习笔记一
  7. Spring IOC容器-注解的方式
  8. derby mysql 同步_[Derby]数据库操作说明
  9. linux时间与日期函数,Shell中关于时间和日期的函数总结
  10. 转录组分析_肠道菌群:宏转录组测序分析流程解读
  11. “我们必须禁止互联网定向广告!”
  12. 惊爆:各大 App 可直接打开小程序!微信收割移动互联网的时间开始了
  13. ubuntu安装jdk全过程-转
  14. delphi 获取操作系统版本_Ubuntu 20.04 LTS已可通过Windows 10应用商店获取
  15. matlab 高阶(二) —— 数值、溢出问题的解决
  16. Cakephp 创建无模型的Controller
  17. 虚拟机系统iso镜像下载_如何下载正版系统镜像
  18. shl归纳推理测试题库_笔经总结含征服shl功略
  19. pdf格式文件转换成mobi
  20. js 获取当天23点59分59秒 时间戳

热门文章

  1. 机器学习笔记(四)---- 逻辑回归的多分类
  2. 【华为云技术分享】《跟唐老师学习云网络》 - Tcpdump大杀器抓包
  3. php parseint,JavaScript parseInt() 函数
  4. LeetCode-118杨辉三角C++详解
  5. Mac中常用的终端配置命令总结
  6. python语言三大基本控制结构_Python基础知识之4——三大控制结构
  7. 油猴脚本使用waitForKeyElements报错eslint: no-undef - `waitForKeyElements` is not defined
  8. JSON 数据格式(基础知识)
  9. mysql 吧库下的表名都加_MySQL 数据库名、表名、字段名大小写敏感记录
  10. oracle 分析函数_数据分析系列笔试题(6)