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. 2017ACM暑期多校联合训练 - Team 1 1003 HDU 6035 Colorful Tree (dfs)

    题目链接 Problem Description There is a tree with n nodes, each of which has a type of color represented ...

  2. TP中搜索条件

  3. Tinyos 第三版Make系统

    1.make系统安装 cd tools ./Bootstrap ./configure make sudo make install 2.make系统结构 3.第三版Makerules文件部分解析 # ...

  4. 某团队线下赛AWD writeup&Beescms_V4.0代码审计

    还是跟上篇一样.拿别人比赛的来玩一下.  0x01 预留后门 连接方式: 0x02 后台登录口SQL注入 admin/login.php 在func.php当中找到定义的check_login函数 很 ...

  5. linux/centos定时任务cron

    https://www.cnblogs.com/p0st/p/9482167.html cron: crond进程 crontab修改命令 * * * * *  command parameter & ...

  6. input只读属性 设置和移除 选择数字

    设置只读属性 $('#stage').attr("readonly", "readonly"); 移除 只读属性  $("input").r ...

  7. 9. Swarm mode

  8. csu 1556(快速幂)

    1556: Jerry's trouble Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 787  Solved: 317[Submit][Statu ...

  9. 不需要打密码的sudo方法

    Linux下频繁输入sudo很麻烦.如果你的账户已经是sudoer了,那么编辑/etc/sudoers,将 %sudo ALL=(ALL:ALL) ALL 修改为: %sudo ALL=(ALL) N ...

  10. 关闭windows 7的自动休眠功能

    powercfg -h off powercfg -h on https://www.tulaoshi.com/n/20160401/2075397.html powercfg -h on 该文章&l ...