4552: [Tjoi2016&Heoi2016]排序

Time Limit: 60 Sec  Memory Limit: 256 MB
Submit: 2703  Solved: 1386
[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

Sample Output

5

这题直接排序肯定T到飞起,然后我们考虑其他做法(废话)
瞎yy仔细分析后这也是个区间问题阿,考虑能不能用线段树维护。
发现说是排序,但是最主要的关系还是之和大小关系有关啊,所以把这个问题抽象成一个01序列
我们可以二分答案,每次check都把所有操作重新进行一遍。这只是个大体思路,我们还要考虑其正确性。
为什么要二分答案,因为把问题转化成01序列后0或1代表该数与目标的大小关系,如果当前的该位置比目标大,那肯定是将区间左断点变大啊
至于决策单调性,博主比较mengbi。有大佬会可以指出阿
现在我们考虑怎么对每个更改进行操作,前面我们说过,01代表的是某个数与目标的大小关系,那我们在排序时只需利用这个性质,对于升序排序,把区间中所有0甩到左边,把1甩到右边,如果降序反过来。
这样我们在二分答案时只需检测询问位置是否为1即可。
对于这这些操作只需维护一棵支持区间覆盖,区间修改的线段数即可。
注意点:在懒标记下传和赋值时,要直接赋值而不是累加。
    要加特判(代码中有注释),因为check()函数中的 change(1,1,n,ql[i],ql[i]+num-1,1)会导致右端点小于左端点
 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
const int N=1e5+;
using namespace std;
int mid,sum1,q;
int n,m;
int a[N];
struct node{
int l,r,opt;
}ask[N];
struct NODE{
int l,r,val,f;
}tr[N<<];
void build(int p,int l,int r){//cout<<"B"<<endl;
tr[p].l=l,tr[p].r=r;
if(l==r){//cout<<"break"<<endl;
tr[p].f=-;
tr[p].val=(a[l]>=mid);
return ;
}
tr[p].f=-;
int mid=(l+r)>>;
build(p<<,l,mid);
build(p<<|,mid+,r);
tr[p].val=tr[p<<].val+tr[p<<|].val;
}
void down(int p){
if(tr[p].f<) return ;
tr[p<<].f=tr[p].f;
tr[p<<|].f=tr[p].f;//lanbiaojizhijiefugai
tr[p<<].val=(tr[p<<].r-tr[p<<].l+)*tr[p].f;
tr[p<<|].val=(tr[p<<|].r-tr[p<<|].l+)*tr[p].f;
tr[p].f=-;
}
void change(int p,int l,int r,int val){
if(l<=tr[p].l&&tr[p].r<=r){
tr[p].f=val;
tr[p].val=(tr[p].r-tr[p].l+)*val;//zhijiefuzhi//
return ;
}
if(l>tr[p].r||r<tr[p].l) return ;
down(p);
int mid=(tr[p].l+tr[p].r)>>;
if(l<=mid) change(p<<,l,r,val);
if(r>mid) change(p<<|,l,r,val);
tr[p].val=tr[p<<].val+tr[p<<|].val;
}
void query(int p,int l,int r){//cout<<p<<" "<<l<<" "<<r<<endl;
if(l<=tr[p].l&&tr[p].r<=r){//cout<<"break"<<endl;
sum1+=tr[p].val;//
return ;
}
if(l>tr[p].r||r<tr[p].l) return ;//特判
down(p);
int mid=(tr[p].l+tr[p].r)>>;
if(l<=mid)query(p<<,l,r);
if(r>mid)query(p<<|,l,r);
}
bool check(int x){
build(,,n);
for(int i=;i<=m;i++){
sum1=;query(,ask[i].l,ask[i].r);
if(ask[i].opt==){//升序
//cout<<"Q"<<endl;
change(,ask[i].l,ask[i].r-sum1,);//
change(,ask[i].r-sum1+,ask[i].r,);//
}
else{
//cout<<"Q"<<endl;
change(,ask[i].l+sum1,ask[i].r,);
change(,ask[i].l,ask[i].l+sum1-,);
}
}
//for(int i=1;i<=n;i++) cout<<tr[i].val<<" ";
sum1=;
query(,q,q);
//cout<<sum1<<endl;
if(sum1) return true;
else return false;
}
int main(){
//freopen("sort9.in","r",stdin);
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
for(int i=;i<=m;i++){
scanf("%d%d%d",&ask[i].opt,&ask[i].l,&ask[i].r);
}
scanf("%d",&q);
int l=,r=n,ans;
while(l<r){//cout<<"K"<<endl;
mid=(l+r)>>;//cout<<l<<" "<<r<<" "<<mid<<endl;
//cout<<check(mid)<<endl;
if(check(mid)) ans=mid/*?*/,l=mid+;
else r=mid;
}
printf("%d",ans);
}

[HEOI2016&TJOI2016] 排序(线段树)的更多相关文章

  1. [HEOI2016/TJOI2016]排序 线段树+二分

    [HEOI2016/TJOI2016]排序 内存限制:256 MiB 时间限制:6000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 在2016年,佳媛姐姐喜欢上了数字序列.因而 ...

  2. [Luogu P2824] [HEOI2016/TJOI2016]排序 (线段树+二分答案)

    题面 传送门:https://www.luogu.org/problemnew/show/P2824 Solution 这题极其巧妙. 首先,如果直接做m次排序,显然会T得起飞. 注意一点:我们只需要 ...

  3. luoguP2824 [HEOI2016/TJOI2016]排序(线段树分裂做法)

    题意 所谓线段树分裂其实是本题的在线做法. 考虑如果我们有一个已经排好序的区间的权值线段树,那么就可以通过线段树上二分的方法得到第\(k\)个数是谁. 于是用set维护每个升序/降序区间的左右端点以及 ...

  4. 洛谷$P2824\ [HEOI2016/TJOI2016]$ 排序 线段树+二分

    正解:线段树+二分 解题报告: 传送门$QwQ$ 昂着题好神噢我$jio$得$QwQQQQQ$,,, 开始看到长得很像之前考试题的亚子,,,然后仔细康康发现不一样昂$kk$,就这里范围是$[1,n]$ ...

  5. BZOJ.4552.[HEOI2016/TJOI2016]排序(线段树合并/二分 线段树)

    题目链接 对于序列上每一段连续区间的数我们都可以动态开点建一棵值域线段树.初始时就是\(n\)棵. 对于每次操作,我们可以将\([l,r]\)的数分别从之前它所属的若干段区间中分离出来,合并. 对于升 ...

  6. Luogu P2824 [HEOI2016/TJOI2016]排序 线段树+脑子

    只会两个$log$的$qwq$ 我们二分答案:设答案为$ans$,则我们把$a[i]<=ans$全部设成$0$,把$a[i]>ans$全部设成$1$,扔到线段树里,这样区间排序(升序)就是 ...

  7. day 1 晚上 P2824 [HEOI2016/TJOI2016]排序 线段树

    #include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #inclu ...

  8. 排序HEOI2016/TJOI2016 二分+线段树判定

    LINK:排序 此题甚好我一点思路都没有要是我当时省选此题除了模拟我恐怕想不到还可以二分 还可以线段树... 有点ex 不太好写 考虑 暴力显然每次给出询问我们都是可以直接sort的 无视地形无视一切 ...

  9. BZOJ4552 HEOI/TJOI2016 排序 线段树、二分答案

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=4552 题意:给出一个$1$到$N$的全排列,对其进行$M$次排序,每次排序将区间$[l ...

  10. 2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串)

    2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串) https://www.luogu.com.cn/problem/P2824 题意: 在 20 ...

随机推荐

  1. Redis-数据结构与对象-对象

    1. 作用 Redis使用对象作为五种不同类型的底层实现,字符串,列表,哈希,集合,有序集合等 而对象是基于之前的分析的数据结构创建的.每个对象都至少用到一种数据结构,这意味着,Redis五大类型,底 ...

  2. Codeforces 1178E. Archaeology

    传送门 首先一定有解,考虑归纳法证明 首先 $n<=3$ 时显然 考虑 $n=4$ 时,那么因为 $s[1]!=s[2],s[3]!=s[4]$ ,并且 $s[i] \in {a,b,c}$ 由 ...

  3. 怎样创建并使用 vue 组件 (component) ?

    组件化开发 需要使用到组件, 围绕组件, Vue 提供了一系列功能方法, 这里仅记录组件的 最简单 的使用方法. 1. 通过 Vue.component(tagName, options) 注册一个 ...

  4. OnMouseWheel的通常处理

    BOOL CMainWindow::OnMouseWheel(UINT nFlags, short zDelta, CPoint point) { BOOL bUp = TRUE; int nDelt ...

  5. 在Windows平台上运行Tomcat

    从之前的学习中知道,可以调用Bootstrap类将Toomcat作为一个独立的应用程序来运行,在Windows平台上,可以调用startup.bat批处理文件来启动Tomcat,或运行shutdown ...

  6. 对接外网post,get接口封装类库

    public class HttpHelper { public static string GetAsync(string url)  { HttpWebRequest request = WebR ...

  7. arcgisJs之featureLayer中feature的获取

    arcgisJs之featureLayer中feature的获取 在featureLayer中source可以获取到一个Graphic数组,但是这个数组属于原数据数组.当使用 applyEdits修改 ...

  8. 电脑连手机调试app

    小米6也真是坑,打开开发者模式的方式堪称一流绝密!!! 设置 --> 我的设备 --> 全部参数 --> MIUI版本 --> 连续点击七次,直到提示已经处于开发者模式为止 然 ...

  9. Dreamweaver CS6 破解安装

    安装 双击Dreamweaver.dmg文件,然后Command+N,新建一个Finder,接着将Adobe Dreamweaver CS6拖到新建Finder的应用程序中.   在Finder中应用 ...

  10. 百度编辑神器ueditor在ajax或form提交内容时候异常

    百度编辑神器ueditor在ajax或form提交内容时候异常,一:⑴web.config中<system.web> <httpRuntime requestValidationMo ...