【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那样统计答案.但是发现这样时间空间复杂度都很爆炸,所以考虑预处理,可以用主席树来做 ...
随机推荐
- [Hibernate] 注解映射例子
Hibernate 注解(Hibernate Annotation) 是一种比较新的方式,通过在 java 简单类增加注解,来声明 java 类和数据库表的映射,作用和 xml 文件相似.hibern ...
- hpuoj 问题 A: 做不出来踢协会!!!
问题 A: 做不出来踢协会!!! 时间限制: 1 Sec 内存限制: 128 MB提交: 291 解决: 33[提交][状态][讨论版] 题目描述 这是今天最水的一道题,如果没写出来的,呵呵,踢协 ...
- C#-Mdi多文档窗体及其子窗体的排列 ---ShinePans
MdiLayout枚举成员及说明 Casecade s全部Mdi层叠在父窗体 TileHorizontal 水平平铺 TitleVertical 垂直平铺 Form1.cs (mdi) using S ...
- photoshopcs5 win7安装报错的解决
因为之前安装了绿色中文破解版的PhotoShop CS5,虽然卸载了,但是注册表还可能残留了其它信息,导致在安装Adobe PhotoShop CS5英文版时一直显示 (Exit Code: 7 ER ...
- android 22 启动带2个action值的预定义acticity
main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" andro ...
- Qt 学习之路:元素布局
上一章我们介绍了 QML 中用于定位的几种元素,被称为定位器.除了定位器,QML 还提供了另外一种用于布局的机制.我们将这种机制成为锚点(anchor).锚点允许我们灵活地设置两个元素的相对位置.它使 ...
- XML解析技术研究(一)
摘要:XML作为过去十年中出现的最流行的技术之一,得到了广泛的应用,而其中XML解析技术是XML应用的关键.本文介绍了XML解析技术的研究动向,分析和比较了4种XML解析技术的优劣,并归纳总结了应 ...
- Qt解析XML文件(QXmlStreamReader)
(2013-08-03 10:53:53) 转载▼ 如何使用QXmlStreamReader来解析格式良好的XML,Qt的文档中指出,它是一种更快.更方便的Qt自己的SAX解析器(QXml ...
- Tomcat7.0.40 基于DataSourceRealm的和JDBCRealm的资源用户访问控制
软件版本: Tomcat 7.0.40 Mysql: 5.1 Host: CentOS 6.3 64bit 使用JDBCRealm (Tomcat 会使用所给的JDBC Connecter 自己去连M ...
- [转] 学习使用:before和:after伪元素
http://www.w3cplus.com/css3/learning-to-use-the-before-and-after-pseudo-elements-in-css.html 如果你一直密切 ...