【BZOJ2653】【主席树+二分】middle
Description
一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整。
给你一个长度为n的序列s。
回答Q个这样的询问:s的左端点在[a,b]之间,右端点在[c,d]之间的子序列中,最大的中位数。
其中a<b<c<d。
位置也从0开始标号。
我会使用一些方式强制你在线。
Input
第一行序列长度n。
接下来n行按顺序给出a中的数。
接下来一行Q。
然后Q行每行a,b,c,d,我们令上个询问的答案是x(如果这是第一个询问则x=0)。
令数组q={(a+x)%n,(b+x)%n,(c+x)%n,(d+x)%n}。
将q从小到大排序之后,令真正的要询问的a=q[0],b=q[1],c=q[2],d=q[3]。
输入保证满足条件。
Output
Q行依次给出询问的答案。
Sample Input
5
170337785
271451044
22430280
969056313
206452321
3
3 1 0 2
2 3 1 4
3 1 4 0 271451044
271451044
969056313
Sample Output
Hint
0:n,Q<=100
1,...,5:n<=2000
0,...,19:n<=20000,Q<=25000
Source
【分析】
居然wa了一下TAT.
比较简单的题目,按照权值大小初始化一下线段树将其可持久化,对于二分的版本求前缀和的最大最小值减一下看是否大于等于0就可以了。
/*
唐代贾岛
《剑客 / 述剑》
十年磨一剑,霜刃未曾试。
今日把示君,谁有不平事?
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
#include <iomanip>
#include <string>
#include <cmath>
#include <queue>
#include <assert.h>
#include <map>
#include <ctime>
#include <cstdlib>
#include <stack>
#define LOCAL
const int INF = 0x7fffffff;
const int MAXN = + ;
const int maxnode = * + * ;
const int maxm= * + ;
using namespace std;
struct DATA{
int num;
int order;
bool operator < (const DATA &b)const{
return num < b.num;
}
}sorted[MAXN];
int data[MAXN];
struct Node{
int l, r;
int Max, val, sum, Min;
Node *ch[];
}*root[MAXN], mem[maxnode];
int tot, n; Node *NEW(int l, int r){
Node *p = &mem[tot++];
p->l = l;
p->r = r;
p->val = p->sum = p->Max = p->Min = ;
p->ch[] = p->ch[] = NULL;
return p;
}
void update(Node *&t){
if (t->l == t->r) return;
t->sum = ;
if (t->ch[] != NULL) t->sum += t->ch[]->sum;
if (t->ch[] != NULL) t->sum += t->ch[]->sum; t->Max = max(t->ch[]->Max + t->ch[]->sum, t->ch[]->Max);
t->Min = min(t->ch[]->Min + t->ch[]->sum, t->ch[]->Min);
return;
}
void build(Node *&t, int l, int r){
if (t == NULL){
t = NEW(l, r);
}
if (l == r) return;
int mid = (l + r) >> ;
build(t->ch[], l, mid);
build(t->ch[], mid + , r);
update(t);
}
//将l改为-1
void change(Node *&t, Node *&last, int l){
if (t == NULL){
t = NEW(last->l, last->r);
t->val = last->val;
t->Max = last->Max;
t->Min = last->Min;
t->sum = last->sum;
}
if (t->l == l && t->r == l){
t->Min = t->Max = t->sum = -;
return;
}
int mid = (t->l + t->r) >> ;
if (l <= mid){
change(t->ch[], last->ch[], l);
t->ch[] = last->ch[];
}else{
change(t->ch[], last->ch[], l);
t->ch[] = last->ch[];
}
update(t);
}
int qSum(Node *t, int l, int r){
if (l > r) return ;
if (l == ) return qSum(t, l + , r); if (l <= t->l && t->r <= r) return t->sum;
int mid = (t->l + t->r) >>;
int sum = ;
if (l <= mid) sum += qSum(t->ch[], l, r);
if (r > mid) sum += qSum(t->ch[], l, r);
return sum;
}
int qMax(Node *t, int l, int r, int k){
if (l == ) return max(, qMax(t, l + , r, k)); if (l <= t->l && t->r <= r) return t->Max + qSum(root[k], , t->l - );
int mid = (t->l + t->r) >> ;
int Ans = -INF;
if (l <= mid) Ans = max(Ans, qMax(t->ch[], l, r, k));
if (r > mid) Ans = max(Ans, qMax(t->ch[], l, r, k));
return Ans;
}
int qMin(Node *t, int l, int r, int k){
if (l == ) return min(, qMin(t, l + , r, k)); if (l <= t->l && t->r <= r) return t->Min + qSum(root[k], , t->l - );
int mid = (t->l + t->r) >> ;
int Ans = INF;
if (l <= mid) Ans = min(Ans, qMin(t->ch[], l, r, k));
if (r > mid) Ans = min(Ans, qMin(t->ch[], l, r, k));
return Ans;
} void init(){
scanf("%d", &n);
for (int i = ; i <= n; i++){
sorted[i].order = i;
scanf("%d", &sorted[i].num);
data[i] = sorted[i].num;
}
//离散化
sort(sorted + , sorted + + n); tot = ;
root[] = NULL;
build(root[], , n);
//开始可持久化
for (int i = ; i <= (n + ); i++) change(root[i], root[i - ], sorted[i - ].order);
//printf("%d", root[6]->Max);
/*int cnt = 0;
for (int i = 1; i <= n; i++){
if (i == 0 || sorted[i].num != sorted[i - 1].num) cnt++;
rem[cnt] = sorted[i].num;
data[sorted[i].order] = cnt;
}*/
//for (int i = 1; i <= n; i++)
}
int search(int a, int b, int c, int d){
int Ans, l = , r = n;
while (l <= r){
int mid = (l + r) >> ;
if ((qMax(root[mid], c, d, mid) - qMin(root[mid], a, b, mid)) >= ) Ans = mid, l = mid + ;
else r = mid - ;
}
return Ans;
}
void work(){
int last_ans = , m;
scanf("%d", &m);
for (int i = ; i <= m; i++){
int q[];
for (int j = ; j <= ; j++){
scanf("%d", &q[j]);
q[j] = (q[j] + last_ans) % n;
}
sort(q + , q + + );
int a = q[], b = q[], c = q[], d = q[];
a++;c++;
b++;d++;
//printf("%d", qMax(root[5], 3, 3, 5));
//printf("%d%d%d%d\n", a, b, c, d);
last_ans = sorted[search(a - , b - , c, d)].num;
printf("%d\n", last_ans);
}
} int main (){ init();
work();
return ;
}
【BZOJ2653】【主席树+二分】middle的更多相关文章
- 2018湘潭邀请赛C题(主席树+二分)
题目地址:https://www.icpc.camp/contests/6CP5W4knRaIRgU 比赛的时候知道这题是用主席树+二分,可是当时没有学主席树,就连有模板都不敢套,因为代码实在是太长了 ...
- BZOJ.1926.[SDOI2010]粟粟的书架(前缀和 主席树 二分)
题目链接 题意: 在给定矩形区域内找出最少的数,满足和>=k.输出数的个数.两种数据范围. 0~50 注意到(真没注意到...)P[i,j]<=1000,我们可以利用前缀和预处理. num ...
- 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)
Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...
- HDU - 4866 主席树 二分
题意:在x轴\([1,X]\)内的上空分布有n个占据空间\([L_i,R_i]\),高度\(D_i\)的线段,射中线段的得分为其高度,每次询问从x轴的\(x\)往上空射的最近k个线段的总得分,具体得分 ...
- POJ 6621: K-th Closest Distance(主席树 + 二分)
K-th Closest Distance Time Limit: 20000/15000 MS (Java/Others) Memory Limit: 524288/524288 K (Jav ...
- HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分)
HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分) 传送门:http://acm.hdu.edu.cn/showproblem.php? ...
- [BZOJ2653]middle 主席树+二分
2653: middle Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2042 Solved: 1123[Submit][Status][Disc ...
- 【bzoj2653】【middle】【主席树+二分答案】
Description 一个长度为 n 的序列 a ,设其排过序之后为 b ,其中位数定义为 b[n/2] ,其中 a,b 从 0 开始标号 , 除法取下整. 给你一个长度为 n 的序列 s .回答 ...
- bzoj 2653: middle (主席树+二分)
2653: middle Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2522 Solved: 1434[Submit][Status][Disc ...
- BZOJ 2653: middle(主席树+二分答案)
传送门 解题思路 首先可以想到一种暴力做法,就是询问时二分,然后大于等于这个值的设为1,否则设为-1,然后就和GSS1那样统计答案.但是发现这样时间空间复杂度都很爆炸,所以考虑预处理,可以用主席树来做 ...
随机推荐
- HDOJ/HDU 2555 人人都能参加第30届校田径运动会了(判断加排序~)
Problem Description 杭州师范大学第29届田径运动会圆满的闭幕了,本届运动会是我校规模最大,参赛人数最多的一次运动会.在两天半时间里,由学生.教工组成的61支代表队共2664名运动员 ...
- HDOJ 1716 排列2 next_permutation函数
Problem Description Ray又对数字的列产生了兴趣: 现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数. Input 每组数据占一行,代表四张卡 ...
- HDOJ 1032(POJ 1207) The 3n + 1 problem
Description Problems in Computer Science are often classified as belonging to a certain class of pro ...
- nginx主配置文件 在那找怎么打开
- LOL游戏程序中对一些函数的Hook记录(Win10 x64)
[PC Hunter Standard][League of Legends.exe-->Ring3 Hook]: 108Hooked Object Hook Address and Locat ...
- 定制Centos系统(基于6.x)
1.条件准备: 按照需求,最小化安装Centos原生系统 在安装后的系统中找到/root/install.log与/root/anaconda-ks.cfg文件 ...
- AIX操作oracle
oracle:出现下述错误,无法连接用户. ORA-01034: ORACLE not available ORA-27101: shared memory realm does not exist ...
- Mina学习之IoBuffer
IoBuffer是一个被MINA体系所使用的字节数组.它是ByteBuffer的替代品,Mina不使用NIO的ByteBuffer有两个原因: 1. ByteBuffer没有提供更多有用的api,如f ...
- UIPickView的简单介绍
UIPickView的简单介绍 设置UIPickView的时候,我们主要需要设置一下下面的两个属性 UIPickerView *pickView1; pickView1 = [[UIPickerVie ...
- block没那么难(三):block和对象的内存管理
本系列博文总结自<Pro Multithreading and Memory Management for iOS and OS X with ARC> 在上一篇文章中,我们讲了很多关于 ...