2653: middle

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 2381  Solved: 1340
[Submit][Status][Discuss]

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]。  
输入保证满足条件。
第一行所谓“排过序”指的是从小到大排序!
n<=20000,Q<=25000
 

Output

Q行依次给出询问的答案。

Sample Input

5
170337785
271451044
22430280
969056313
206452321
3
3 1 0 2
2 3 1 4
3 1 4 0

Sample Output

271451044
271451044
969056313

HINT

 

Source

 

[Submit][Status][Discuss]

HOME Back

clj dalao出的神题%%%

一道很好的思维题吧。首先可以发现,满足条件的中位数是具有二分性(即单调性)的。比如数列中一个数$x$,我们把所有比$x$小的数的位置标记成-1,比$x$大的数的位置标记成1,如果和大于0,表示比它大的数枚举多了,所以把答案往右移,反之往左移。满足二分性,所以二分check时满足区间最大值>=0就表示这个数可以作为答案,更新答案。(<=0也可以用来判断,不过维护的是最小值即可)

可以发现,问题中的$bc$区间一定被包括,所以查询$ab$的右缀连续区间最大值和$cd$的左缀连续区间最大值以及$bc$的整个区间和即可。【注意】所有区间都是左闭右开。

考虑如何维护。给每个值建一棵主席数,预处理出每棵主席数上-1和1的情况,每次就在对应二分的pos的主席树上查询即可。

最后是合并节点的问题,$lmax$是从左儿子的$lmax$或者左儿子的$sum$加右儿子的$lmax$更新过来,$rmax$同理。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std; int n, ans, a, b, c, d, q[]; struct QwQ {
int v, id;
} A[];
bool cmp ( QwQ a, QwQ b ) { return a.v < b.v; } struct node {
node *ls, *rs;
int sum, lmax, rmax;
void update ( ) {
sum = ls -> sum + rs -> sum;
lmax = max ( ls -> lmax, ls -> sum + rs -> lmax );
rmax = max ( rs -> rmax, rs -> sum + ls -> rmax );
}
} *zero, *root[], pool[*], *tail = pool; node *newnode ( ) {
node *nd = ++ tail;
nd -> ls = zero; nd -> rs = zero;
nd -> sum = ; nd -> lmax = ; nd -> rmax = ;
return nd;
} node *build ( int l, int r ) {
node *nd = newnode ( );
if ( l == r ) {
nd -> sum = nd -> lmax = nd -> rmax = ;
return nd;
}
int mid = ( l + r ) >> ;
nd -> ls = build ( l, mid );
nd -> rs = build ( mid + , r );
nd -> update ( );
return nd;
} void init ( ) {
zero = ++ tail;
zero -> ls = zero; zero -> rs = zero; zero -> sum = ;
zero -> lmax = ; zero -> rmax = ;
root[] = build ( , n );
} node *insert ( node *nd, int l, int r, int pos ) {
node *nnd = newnode ( );
if ( l == r ) { nnd -> sum = -; nnd -> lmax = nnd -> rmax = -; return nnd; }
int mid = ( l + r ) >> ;
if ( mid >= pos ) {
nnd -> rs = nd -> rs;
nnd -> ls = insert ( nd -> ls, l, mid, pos );
} else {
nnd -> ls = nd -> ls;
nnd -> rs = insert ( nd -> rs, mid + , r, pos );
}
nnd -> update ( );
return nnd;
} int query_s ( node *nd, int l, int r, int L, int R ) {
if ( L > R ) return ;
if ( l >= L && r <= R ) return nd -> sum;
int mid = ( l + r ) >> , ans = ;
if ( L <= mid ) ans += query_s ( nd -> ls, l, mid, L, R );
if ( R > mid ) ans += query_s ( nd -> rs, mid + , r, L, R );
return ans;
} int query_l ( node *nd, int l, int r, int L, int R ) {
if ( L > R ) return ;
if ( l >= L && r <= R ) return nd -> lmax;
int mid = ( l + r ) >> , ans = ;
if ( L <= mid ) ans = max ( ans, query_l ( nd -> ls, l, mid, L, R ) );
if ( R > mid ) {
int lsum = query_s ( nd -> ls, l, mid, L, mid );
int rmaxl = query_l ( nd -> rs, mid + , r, L, R );
ans = max ( ans, lsum + rmaxl );
}
return ans;
} int query_r ( node *nd, int l, int r, int L, int R ) {
if ( L > R ) return ;
if ( l >= L && r <= R ) return nd -> rmax;
int mid = ( l + r ) >> , ans = ;
if ( R > mid ) ans = max ( ans, query_r ( nd -> rs, mid + , r, L, R ) );
if ( L <= mid ) {
int rsum = query_s ( nd -> rs, mid + , r, mid + , R );
int lmaxr = query_r ( nd -> ls, l, mid, L, R );
ans = max ( ans, rsum + lmaxr );
}
return ans;
} bool check ( int pos ) {
int ab = query_r ( root[pos], , n, a, b - );
int cd = query_l ( root[pos], , n, c + , d );
int bc = query_s ( root[pos], , n, b, c );
if ( ab + cd + bc >= ) return ;
return ;
} int find ( ) {
int l = , r = n, ans = ;
while ( l <= r ) {
int mid = ( l + r ) >> ;
if ( check ( mid ) ) {
ans = mid; l = mid + ;
} else r = mid - ;
}
return ans;
} int main ( ) {
scanf ( "%d", &n );
init ( );
for ( int i = ; i <= n; i ++ ) {
scanf ( "%d", &A[i].v ); A[i].id = i;
}
sort ( A + , A + + n, cmp );
for ( int i = ; i <= n; i ++ )
root[i] = insert ( root[i-], , n, A[i-].id );
int Q;
scanf ( "%d", &Q );
while ( Q -- ) {
for ( int i = ; i <= ; i ++ ) {
int x; scanf ( "%d", &x );
q[i] = ( x + ans ) % n + ;
}
sort ( q + , q + );
a = q[], b = q[], c = q[], d = q[];
ans = A[find ( )].v;
printf ( "%d\n", ans );
}
return ;
}

【BZOJ】2653: middle的更多相关文章

  1. 【BZOJ】3052: [wc2013]糖果公园

    http://www.lydsy.com/JudgeOnline/problem.php?id=3052 题意:n个带颜色的点(m种),q次询问,每次询问x到y的路径上sum{w[次数]*v[颜色]} ...

  2. 【BZOJ】3319: 黑白树

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 题意:给一棵n节点的树(n<=1e6),m个操作(m<=1e6),每次操作有两种: ...

  3. 【BZOJ】3319: 黑白树(并查集+特殊的技巧/-树链剖分+线段树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 以为是模板题就复习了下hld............................. 然后n ...

  4. 【BZOJ】1013: [JSOI2008]球形空间产生器sphere

    [BZOJ]1013: [JSOI2008]球形空间产生器sphere 题意:给n+1个n维的点的坐标,要你求出一个到这n+1个点距离相等的点的坐标: 思路:高斯消元即第i个点和第i+1个点处理出一个 ...

  5. 【BZOJ】1002:轮状病毒(基尔霍夫矩阵【附公式推导】或打表)

    Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图 ...

  6. 【BZOJ】【3083】遥远的国度

    树链剖分/dfs序 其实过了[BZOJ][4034][HAOI2015]T2以后就好搞了…… 链修改+子树查询+换根 其实静态树的换根直接树链剖分就可以搞了…… 因为其实只有一样变了:子树 如果roo ...

  7. 【BZOJ】【2434】【NOI2011】阿狸的打字机

    AC自动机+DFS序+BIT 好题啊……orz PoPoQQQ 大爷 一道相似的题目:[BZOJ][3172][TJOI2013]单词 那道题也是在fail树上数有多少个点,只不过这题是在x的fail ...

  8. 【BZOJ】【2738】&【Tsinsen】【A1333】矩阵乘法

    整体二分+树状数组 过了[BZOJ][2527][POI2011]Meteors以后这题就没那么难啦~ 关键是[从小到大]依次插入数字,然后整体二分每个查询的第k大是在第几次插入中被插入的……嗯大概就 ...

  9. 【BZOJ】【3170】【TJOI2103】松鼠聚会

    切比雪夫距离+曼哈顿距离 题解:http://www.cnblogs.com/zyfzyf/p/4105456.html 其实应该先做这题再做[BZOJ][3210]花神的浇花集会的吧…… 我们发现d ...

随机推荐

  1. laravel学习教程整理

    百度传课:https://chuanke.baidu.com/v5847462-219167-1421398.html

  2. Java的继承和多态

    看了博客园里面的一个文章,关于java的继承和多态: class A ...{ public String show(D obj)...{ return ("A and D"); ...

  3. Mysql储存过程6: in / out / inout

    in 为向函数传送进去的值 out 为函数向外返回的值 intout 传送进去的值, 并且还返回这个值 )) begin then select 'true'; else select 'false' ...

  4. discuz 积分按日重新计算,(摒弃以前24小时计算)

    修改\source\module\forum\forum_misc.php将 foreach(C::t('forum_ratelog')->fetch_all_sum_score($_G['ui ...

  5. python基础===string模块常量

    In [8]: import string In [9]: dir(string) In [10]: string.ascii_letters Out[10]: 'abcdefghijklmnopqr ...

  6. 148.Sort List---链表排序(冒泡、归并)

    题目链接 题目大意:对链表进行排序,要求时间复杂度是o(nlgn). 法一:冒泡,不交换结点,而交换结点中的数值.超时了.代码如下: public ListNode sortList(ListNode ...

  7. Python连接Access数据库

    前言 今天想要用Python访问Access数据库,折腾了半天,特记录一下 背景 最近想将一些文件记录下来,存入数据库,为此拿LabVIEW写了一个版本,记录环境配置为: LabVIWE:2015 A ...

  8. Web服务器处理动态程序三种方式及Apache配置

    模块.CGI.FastCGI三种方式介绍 以PHP脚本为例: 模块方式是指Web服务器通过libphp5.so模块调用PHP服务,模块将相关函数嵌入Web服务请求处理流程,不需要额外解释器进程.注意, ...

  9. 大型网站的 HTTPS 实践(一)—— HTTPS 协议和原理(转)

    原文链接:http://op.baidu.com/2015/04/https-s01a01/ 1 前言 百度已经于近日上线了全站 HTTPS 的安全搜索,默认会将 HTTP 请求跳转成 HTTPS.本 ...

  10. 设计模式--工厂模式 caffe_layer注册

    来源:http://www.cnblogs.com/zhouqiang/archive/2012/07/20/2601365.html 来源:http://blog.luoyetx.com/2016/ ...