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的更多相关文章

  1. 2018湘潭邀请赛C题(主席树+二分)

    题目地址:https://www.icpc.camp/contests/6CP5W4knRaIRgU 比赛的时候知道这题是用主席树+二分,可是当时没有学主席树,就连有模板都不敢套,因为代码实在是太长了 ...

  2. BZOJ.1926.[SDOI2010]粟粟的书架(前缀和 主席树 二分)

    题目链接 题意: 在给定矩形区域内找出最少的数,满足和>=k.输出数的个数.两种数据范围. 0~50 注意到(真没注意到...)P[i,j]<=1000,我们可以利用前缀和预处理. num ...

  3. 计蒜客 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 ...

  4. HDU - 4866 主席树 二分

    题意:在x轴\([1,X]\)内的上空分布有n个占据空间\([L_i,R_i]\),高度\(D_i\)的线段,射中线段的得分为其高度,每次询问从x轴的\(x\)往上空射的最近k个线段的总得分,具体得分 ...

  5. POJ 6621: K-th Closest Distance(主席树 + 二分)

    K-th Closest Distance Time Limit: 20000/15000 MS (Java/Others)    Memory Limit: 524288/524288 K (Jav ...

  6. HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分)

    HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分) 传送门:http://acm.hdu.edu.cn/showproblem.php? ...

  7. [BZOJ2653]middle 主席树+二分

    2653: middle Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2042  Solved: 1123[Submit][Status][Disc ...

  8. 【bzoj2653】【middle】【主席树+二分答案】

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

  9. bzoj 2653: middle (主席树+二分)

    2653: middle Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2522  Solved: 1434[Submit][Status][Disc ...

  10. BZOJ 2653: middle(主席树+二分答案)

    传送门 解题思路 首先可以想到一种暴力做法,就是询问时二分,然后大于等于这个值的设为1,否则设为-1,然后就和GSS1那样统计答案.但是发现这样时间空间复杂度都很爆炸,所以考虑预处理,可以用主席树来做 ...

随机推荐

  1. Linux学习笔记22——线程属性(转)

    本文来自博客园:http://www.cnblogs.com/yc_sunniwell/archive/2010/06/24/1764204.html 一.线程属性线程具有属性,用pthread_at ...

  2. Eclipse添加快速查找Dao中方法所对应的Mybatis XML映射SQL的插件

    Dao关联Mybatis快速查找的插件安装地址:http://dl.bintray.com/harawata/eclipse 安装步骤: ①Eclipse ==> Help ==> Ins ...

  3. Cogs 1583. [POJ3237]树的维护 LCT,树链剖分

    题目:http://cojs.tk/cogs/problem/problem.php?pid=1583 1583. [POJ3237]树的维护 ★★★☆   输入文件:maintaintree.in  ...

  4. SQLyog之MySQL客户端的下载、安装和使用

    本博文的主要内容有 .SQLyog的下载 .SQLyog的安装 .SQLyog的使用 1.SQLyog的下载 1.进入SQLyog官网,  https://www.webyog.com/en    或 ...

  5. Broken line - SGU 124(判断点与多边形的关系)

    题目大意:RT 分析:构造一条射线,如果穿越偶数条边,那么就在多边形外面,如果穿越奇数条边,那么就在多边形里面. 代码如下: ===================================== ...

  6. Apache-POI操作Excel的一些小技巧

    Apache-POI操作Excel将合并后的单元格全部填充为相同数据的一个实例. private static void fillMergedRegion(final Sheet sheet) { f ...

  7. uva1393 Highways

    留坑(p.339) 已填(膜汪) 每条直线至少经过两个点,我们不妨在经过的所有点中的第二个点统计它 设f[i][j]表示i * j的答案,那么显然可以用f[i][j] = f[i - 1][j] + ...

  8. dom0的cpu hotplug【续】

    上一篇说到,手动xm vcpu-pin住,在hotplug就好了. 本质上,还是因为代码有bug,导致vcpu offline的时候,信息没有清理干净,有残留,当vcpu online的时候,如果调度 ...

  9. HDU2255 奔小康赚大钱【二分图最佳匹配】

    题目链接: http://acm.hdu.edu.cn/showproblem.php? pid=2255 题目大意: 村里要分房子. 有N家老百姓,刚好有N间房子.考虑到每家都要有房住,每家必须分配 ...

  10. MySQL Replication主从复制

    MySQL Replication:NySQL复制,MySQL的复制默认为异步工作模式   mysql的复制功能是mysql内置的,装上它之后就具备了这个功能,而mysql复制是mysql实现大规模高 ...