题目链接


题目大意:


解题思路:

这个题思路很妙!!

  1. 首先我们假设只有一次询问怎么做?
  2. 那么我们可以二分出这个最大值midmidmid,然后把大于等于midmidmid设置成111,把小于midmidmid的设置成−1-1−1,那么就是看看能否构造出一个区间的和大于等于000?
  3. 因为区间两端在[a,b][a,b][a,b]和[c,d][c,d][c,d]之间移动,那么[b+1,c−1][b+1,c-1][b+1,c−1]之间是一定会取到的,为了中位数最大那么区间和肯定要最大!!
  4. 那么就找[a,b][a,b][a,b]里面找最大后缀,和[c,d][c,d][c,d]里面最大的前缀
  5. 所以,对于每一个二分的midmidmid值,建一棵线段树。线段树以区间下标为下标,记录区间和,区间最大后缀,最大前缀。就可以O(logn)O(logn)O(logn)判断midmidmid是否可以更优了。因为中位数一定是在序列里面的,你只要建nnn棵线段树就可以了!
  6. 但是空间炸了呀!!
  7. 要优化空间必须要可持久化去继承,首先我们看一下
  8. 假设我们先排序,从midmidmid到mid+1mid+1mid+1只有一个位置的数字变了就是midmidmid位置上面的值变成了−1-1−1,那么这样子就可以动态开点去继承前面的值,每次修改加O(logn)O(logn)O(logn)空间完美解决

#include <bits/stdc++.h>
#define mid ((l + r) >> 1)
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define log2(a) log(a)/log(2)
#define lowbit(x) ((-x) & x)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define LLF 0x3f3f3f3f3f3f3f3f
#define f first
#define s second
#define endl '\n'
using namespace std;
const int N = 2e6 + 10, mod = 1e9 + 9;
const int maxn = 500010;
const long double eps = 1e-5;
const int EPS = 500 * 500;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
typedef pair<double,double> PDD;
template<typename T> void read(T &x) {x = 0;char ch = getchar();ll f = 1;while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
template<typename T, typename... Args> void read(T &first, Args& ... args) {read(first);read(args...);
}
struct Segtree {int lson, rson;int lsum, rsum, sum;
}tr[maxn << 1];
// lsum 是从左端点起的最长的连续子段和
// rsum 是从右端点起的最长的连续子段和
//sum 是区间和
int n, cnt, root[maxn];
PII arr[maxn];inline void pushup(int rt) {tr[rt].sum = tr[tr[rt].lson].sum + tr[tr[rt].rson].sum;tr[rt].lsum = max(tr[tr[rt].lson].lsum,tr[tr[rt].lson].sum + tr[tr[rt].rson].lsum);tr[rt].rsum = max(tr[tr[rt].rson].rsum,tr[tr[rt].rson].sum + tr[tr[rt].lson].rsum);
}void build(int &rt, int l, int r) {rt = ++ cnt;if(l == r) {tr[rt].lsum = tr[rt].rsum = tr[rt].sum = 1;return;}build(tr[rt].lson,l,mid);build(tr[rt].rson,mid+1,r);pushup(rt);
}void insert(int &now, int pre, int l, int r, int pos, int val = -1) {now = ++ cnt;tr[now] = tr[pre];if(l == r) {tr[now].lsum = tr[now].rsum = tr[now].sum = val;return;}if(pos <= mid) insert(tr[now].lson,tr[pre].lson,l,mid,pos); else insert(tr[now].rson,tr[pre].rson,mid+1,r,pos);pushup(now);
}int quary_sum(int rt, int l, int r, int posl, int posr) {if(posl <= l && posr >= r) return tr[rt].sum;int res = 0;if(posl <= mid) res += quary_sum(tr[rt].lson,l,mid,posl,posr);if(posr > mid) res += quary_sum(tr[rt].rson,mid+1,r,posl,posr);return res;
}int quary_lsum(int rt, int l, int r, int posl, int posr) {if(posl <= l && posr >= r) return tr[rt].lsum;if(posr <= mid) return quary_lsum(tr[rt].lson,l,mid,posl,posr);if(posl > mid) return quary_lsum(tr[rt].rson,mid+1,r,posl,posr);else return max(quary_lsum(tr[rt].lson,l,mid,posl,posr),quary_sum(tr[rt].lson,l,mid,posl,mid)+quary_lsum(tr[rt].rson,mid+1,r,posl,posr));
}int quary_rsum(int rt, int l, int r, int posl, int posr) {if(posl <= l && posr >= r) return tr[rt].rsum;if(posr <= mid) return quary_rsum(tr[rt].lson,l,mid,posl,posr);if(posl > mid) return quary_rsum(tr[rt].rson,mid+1,r,posl,posr);else return max(quary_rsum(tr[rt].rson,mid+1,r,posl,posr),quary_sum(tr[rt].rson,mid+1,r,mid+1,posr)+quary_rsum(tr[rt].lson,l,mid,posl,posr));
}inline bool check(int rt, int a, int b, int c, int d) {int sum = 0;if(c - 1 >= b + 1) sum += quary_sum(root[rt],1,n,b+1,c-1);sum += quary_rsum(root[rt],1,n,a,b);sum += quary_lsum(root[rt],1,n,c,d);return (sum >= 0);
}int main() {IOS;cin >> n;for(int i = 1; i <= n; ++ i) cin >> arr[i].first, arr[i].second = i;sort(arr+1,arr+1+n);build(root[1],1,n);for(int i = 2; i <= n; ++ i)insert(root[i],root[i-1],1,n,arr[i-1].second);int q;cin >> q;int last = 0;while(q --) {int ask[4];for(int i = 0; i < 4; ++ i) {cin >> ask[i];ask[i] = (ask[i] + last) % n + 1;}sort(ask,ask+4);int l = 1, r = n;while(l < r) {int Mid = (l + r + 1) >> 1;if(check(Mid,ask[0],ask[1],ask[2],ask[3])) l = Mid;else r = Mid - 1;}cout << arr[l].first << "\n";last = arr[l].first;}
}

可持久化普通线段树 ---- P2839 [国家集训队]middle 可持久化普通线段树 + 二分 求中位数最大值相关推荐

  1. P2839 [国家集训队]middle(二分 套 主席树)

    P2839 [国家集训队]middle 有一个长度为nnn的序列,有mmm次询问,每次询问a,b,c,da, b, c, da,b,c,d,为l∈[a,b],r∈[c,d]l \in [a, b], ...

  2. 洛谷P2839 [国家集训队]middle(主席树)

    P2839 [国家集训队]middle 我们可以考虑二分中位数 checkcheckcheck 答案,那么我们对于某个值 midmidmid ,把 [l,r][l,r][l,r] 内的所有小于 mid ...

  3. P2839 [国家集训队]middle 二分 + 主席树 在值域上建区间

    传送门 文章目录 题意: 思路: 题意: 思路: 我们先解决怎么判断中位数的问题,我们可以二分一个midmidmid,将<mid<mid<mid的值都变成−1-1−1,其他的数都变成 ...

  4. P2839 [国家集训队]middle

    题面 • 提一下静态区间第k小的nlog2n的做法: 1. 建关于排名的主席树(按排名顺序建树). 2. 二分答案. • 这样做静态区间第k小的虽然有些ZZ,但它的意义在于将线段树   维护的对象改变 ...

  5. bzoj 2653 洛谷 P2839 [国家集训队] middle

    2653: middle Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 2381  Solved: 1340 [Submit][Status][Di ...

  6. 树套树 ----- 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],我们要减去[ ...

  7. [bzoj 2653][国家集训队]middle

    传送门 Description 一个长度为\(n\)的序列\(a\),设其排过序之后为\(b\),其中位数定义为\(b[n/2]\),其中\(a,b\)从\(0\)开始标号,除法取下整. 给你一个长度 ...

  8. [国家集训队]middle(二分+主席树[中位数思维题])

    文章目录 点击查看 solution code 点击查看 solution 简单口胡一下就跑 考虑二分答案ansansans 区间[x1,x2],x1∈[a,b],x2∈[c,d][x1,x2],x1 ...

  9. [回文树][BZOJ2160][国家集训队]拉拉队排练

    Description 艾利斯顿商学院篮球队要参加一年一度的市篮球比赛了.拉拉队是篮球比赛的一个看点,好的拉拉队往往能帮助球队增加士气,赢得最终的比赛.所以作为拉拉队队长的楚雨荨同学知道,帮助篮球队训 ...

最新文章

  1. C++ 笔记(13)— 函数(函数声明、函数定义、函数调用[传值、指针、引用]、函数参数默认值、函数重载)
  2. Environ. Microbiol. | 土壤pH和温度调节农业生态系统中丰富和稀有细菌群落的构建过程...
  3. linux selinux 安全子系统简介
  4. Java必须了解的“递归”与“IO流”!!!
  5. 两个年月日怎么相减_会议记录应该怎么记?看这里
  6. 【转】C++ _T()函数和_L()函数介绍
  7. C语言事实上不简单:sizeof
  8. Python 用装饰器便捷实现多线程
  9. socket简介 - 获取简单网页内容
  10. 翻译: Web 3.0是一种几乎无需信任的承诺的协议/架构
  11. css引入矢量图标_一张矢量图使用css来调用矢量图里的N个图标
  12. 深入理解泊松分布、指数分布、正态分布
  13. 18位身份证号码含义及验证算法代码
  14. 金属类的大宗商品创下新高,对冲基金疯狂买涨
  15. 分布式进阶(十四)分布式开发学习感触
  16. 网宿CDN中标工商银行 服务金融客户布局政企市场
  17. 地图定位技术揭秘(三)
  18. 霍营派出所办理居住证
  19. 文件“无法删除”的处理方法
  20. 台灯显色指数多少合适?专家教你护眼灯怎么选

热门文章

  1. 网络工程师_记录的一些真题_2005下半年上午
  2. 技术19期:1分钟入门数据治理!必看!【技术篇】
  3. 通过对比对象掩码建议的无监督语义分割
  4. 想要去阿里面试?你必须得跨过 JVM 这道坎!
  5. 如何对DevOps数据库进行源代码控制
  6. mysql root的密码忘了?linux下重置mysql的root用户密码。
  7. Linux下同步模式、异步模式、阻塞调用、非阻塞调用总结
  8. RAID0、RAID1、RAID0+1模式实战评测
  9. Win7开机密码破解
  10. 电子邮件的故事:令人吃惊的预测