【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那样统计答案.但是发现这样时间空间复杂度都很爆炸,所以考虑预处理,可以用主席树来做 ...
随机推荐
- HDU-4927 Series 1
http://acm.hdu.edu.cn/showproblem.php?pid=4927 同学用java写的大整数相减 Series 1 Time Limit: 2000/1000 MS (Jav ...
- python string 文本常量和模版
最近在看python标准库这本书,第一感觉非常厚,第二感觉,里面有很多原来不知道的东西,现在记下来跟大家分享一下. string类是python中最常用的文本处理工具,在python的 ...
- ubuntu14.04 wps字体缺失问题
字体 下载安装字体即可
- ANDROID Porting系列二、配置一个新产品
ANDROID Porting系列二.配置一个新产品 详细说明 下面的步骤描述了如何配置新的移动设备和产品的makefile运行android. 1. 目录//vendor/创建一个公 ...
- SRM 409(1-250pt, 1-500pt)
DIV1 250pt 题意:称string s是vector<string> words的ordered superstring,如果它满足:存在一个数列{x0, x1, x2...xm} ...
- conv2用法
1.用法 C=conv2(A,B,shape); %卷积滤波 A:输入图像,B:卷积核 假设输入图像A大小为ma x na,卷积核B大小为mb x nb,则 当sha ...
- matlab初学者_脚本文件调用函数文件
问题: matlab里面有两种文件,一种是脚本文件,一种是函数文件,为了模块化程序,我们需要把专门的功能写成一个函数封装到某个函数文件里面. 那么来看如何在脚本文件里调用函数文件中的函数. 注意点: ...
- Away3d 骨骼动画优化
很多朋友说Away3D 的骨骼数限制在32根,确切的说应该是Stage3D 的限制.在 AGAL2.0之前 VC寄存器是128个,每个vc常量寄存器最大只能容纳4位,transform占用一个4*4的 ...
- android的tabhost+RadioGroup+PopupWindow
根据网上的代码稍作修改了下,放着记录学习. 效果图如下: 主代码如下: package com.andyidea.tabdemo; import android.app.TabActivity; im ...
- Maven实现Web应用集成測试自己主动化 -- 部署自己主动化(WebTest Maven Plugin)
上篇:Maven实现Web应用集成測试自己主动化 -- 測试自己主动化(WebTest Maven Plugin) 之前介绍了怎样在maven中使用webtest插件实现web的集成測试,这里有个遗留 ...