[bzoj4552][Tjoi2016&Heoi2016]排序 二分+线段树
来源:互联网 发布:李谷一 知乎 编辑:程序博客网 时间:2024/05/20 17:41
4552: [Tjoi2016&Heoi2016]排序
Time Limit: 60 Sec Memory Limit: 256 MB[Submit][Status][Discuss]
Description
在2016年,佳媛姐姐喜欢上了数字序列。因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题
,需要你来帮助他。这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排
序分为两种:1:(0,l,r)表示将区间[l,r]的数字升序排序2:(1,l,r)表示将区间[l,r]的数字降序排序最后询问第q
位置上的数字。
Input
输入数据的第一行为两个整数n和m。n表示序列的长度,m表示局部排序的次数。1 <= n, m <= 10^5第二行为n个整
数,表示1到n的一个全排列。接下来输入m行,每一行有三个整数op, l, r, op为0代表升序排序,op为1代表降序
排序, l, r 表示排序的区间。最后输入一个整数q,q表示排序完之后询问的位置, 1 <= q <= n。1 <= n <= 10^5
,1 <= m <= 10^5
Output
输出数据仅有一行,一个整数,表示按照顺序将全部的部分排序结束后第q位置上的数字。
Sample Input
6 3
1 6 2 5 3 4
0 1 4
1 3 6
0 2 4
3
1 6 2 5 3 4
0 1 4
1 3 6
0 2 4
3
Sample Output
5
HINT
对于这道题,我们二分一个权值,大于等于这个权值就为1,否则为0
01线段树排序很简单,大家都会
最后判断这一位是否是1
这种煞笔线段树都花了我半个多小时。。
#include <bits/stdc++.h>const int N = 1e5 + 5;int sum[N<<2], flag[N<<2], jzm_naive, a[N], opt[N], lf[N], rg[N], q, n, m, ans;void update( int k ){ sum[k] = sum[k<<1] + sum[k<<1|1]; }void pushdown( int k, int l, int r ){if( flag[k] != -1 ){int mid = l + r >> 1;sum[k<<1] = ( mid - l + 1 ) * flag[k];sum[k<<1|1] = ( r - mid ) * flag[k];flag[k<<1] = flag[k<<1|1] = flag[k];flag[k] = -1;}}void build( int k, int l, int r ){flag[k] = -1;if( l == r ){sum[k] = ( a[l] >= jzm_naive );return ;}int mid = l + r >> 1;build( k<<1, l, mid );build( k<<1|1, mid + 1, r );update( k );}void modify( int k, int l, int r, int L, int R, int x ){if( L > R ) return ;if( L <= l && r <= R ){sum[k] = ( r - l + 1 ) * x; flag[k] = x;return ;}pushdown( k, l, r );int mid = l + r >> 1;if( L <= mid ) modify( k<<1, l, mid, L, R, x );if( R > mid ) modify( k<<1|1, mid + 1, r, L, R, x );update( k );}int query( int k, int l, int r, int L, int R ){if( L <= l && r <= R ) return sum[k];pushdown( k, l, r );int mid = l + r >> 1, res = 0;if( L <= mid ) res += query( k<<1, l, mid, L, R );if( R > mid ) res += query( k<<1|1, mid + 1, r, L, R );return res;}bool check( int x ){jzm_naive = x;build( 1, 1, n );for( int i = 1; i <= m; i++ ){int tum = query( 1, 1, n, lf[i], rg[i] );if( opt[i] == 0 ){modify( 1, 1, n, lf[i], rg[i] - tum, 0 );modify( 1, 1, n, rg[i] - tum + 1, rg[i], 1 );}else{modify( 1, 1, n, lf[i], lf[i] + tum - 1, 1 );modify( 1, 1, n, lf[i] + tum, rg[i], 0 );}}return query( 1, 1, n, q, q );}int main(){scanf( "%d%d", &n, &m );for( int i = 1; i <= n; i++ ) scanf( "%d", &a[i] );for( int i = 1; i <= m; i++ ) scanf( "%d%d%d", &opt[i], &lf[i], &rg[i] );scanf( "%d", &q );int l = 1, r = n;while( l <= r ){int mid = l + r >> 1;if( check( mid ) ) ans = mid, l = mid + 1;else r = mid - 1;}printf( "%d\n", ans );return 0;}
阅读全文
0 0
- [BZOJ4552][Tjoi2016&Heoi2016][线段树][二分]排序
- [bzoj4552][Tjoi2016&Heoi2016]排序 二分+线段树
- [bzoj4552][Tjoi2016&Heoi2016]排序-二分+线段树
- 【bzoj4552】【Tjoi2016】【Heoi2016】【排序】【二分答案】【线段树】
- [BZOJ4552][Tjoi2016&Heoi2016]排序 二分答案+线段树
- 【二分+线段树】BZOJ4552(Tjoi2016&Heoi2016)[排序]题解
- bzoj4552 [ TJOI2016 && HEOI2016 ] -- 二分+线段树
- 【bzoj4552】【Tjoi2016&Heoi2016】【排序】【线段树】
- BZOJ4552: [Tjoi2016&Heoi2016]排序 线段树
- [BZOJ4552][TJOI2016&HEOI2016]排序-线段树合并
- BZOJ4552 [Tjoi2016&Heoi2016]排序
- bzoj4552【TJOI2016&HEOI2016】排序
- 【bzoj4552】 [Tjoi2016&Heoi2016]排序
- [bzoj4552][Tjoi2016&Heoi2016]排序
- bzoj4552: [Tjoi2016&Heoi2016]排序
- [ 线段树套treap ] [ TJOI2016&&HEOI2016 ] BZOJ4552
- TJOI2016&HEOI2016 排序 线段树+二分答案
- bzoj 4552: [Tjoi2016&Heoi2016]排序 二分答案+线段树
- MD5简单加密
- 单源最短路径算法(Dijkstra算法)
- 蒟蒻复习之-----Tarjan
- 在Linux下安装MySQL
- 文章获取与单词统计排序
- [bzoj4552][Tjoi2016&Heoi2016]排序 二分+线段树
- 河城荷取 二分答案 最大流
- 51Nod 1035 最长的循环节
- [java]创建新数组的三种方式
- 字符串的连接
- HBase之——Shell基础操作
- LeetCode 328. Odd Even Linked List
- 设置坐标轴长度和范围
- python的MySQL操作增删改查