4552: [Tjoi2016&Heoi2016]排序

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

HINT

Source

[Submit][Status][Discuss]

题解:线段树合并与分裂模板题???这题有个非常巧妙的二分答案转化为01序列的线段树做法,也相对好写,但多了一层log。然后快一点的做法是先建立N颗权值线段树,动态开点,记录每个区间下节点个数。一段区间排序就是将这段区间合并。但是前后的区间合并会产生交集,从而就需要分裂,就是我们要取出l,r这段区间,在左右两侧的能延伸进来的线段都要分裂。就对于左边来说l所属的那个区间如果左端点小于l那么就要分开,也就是维护一些不相交的线段,且他们的并是1~n,那么之前几个月虽然这类题没碰过但是听到了很多讨论,肯定是用个set啦,就按照右端点排序,二分一下就可以找到一个点所属的线段。然后就像权值线段树那样查找第k个元素就好了。不过因为有递增递减两种序列,那么就是如果是递减就先减右区间,递增先减左区间。以上内容都是我学着这篇代码理解的。http://www.cnblogs.com/Gloid/p/10204585.html

#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
using namespace std;
const int maxn=1e5+7;
inline ll read()
{ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}
int n,m;
struct node
{int l,r,num;
}no[maxn*80];
int state[maxn],root[maxn];
struct seg
{int l,r;seg(){};seg(int _l,int _r){l=_l;r=_r;}friend bool operator<(seg a,seg b){return a.r<b.r;}
};
set<seg>st;
int cnt;
void insertt(int &x,int l,int r,int pl)
{if(!x)x=++cnt;no[x].num++;if(l==r)return;int mid=(l+r)>>1;if(pl<=mid)insertt(no[x].l,l,mid,pl);else insertt(no[x].r,mid+1,r,pl);
}
void split(int &x,int &y,int k,int op)
{if(!x)return;y=++cnt;no[y].num=no[x].num-k;no[x].num=k;if(op==0){if(no[no[x].l].num==k){no[y].r=no[x].r;no[x].r=0;return;}else if(no[no[x].l].num>k){no[y].r=no[x].r;no[x].r=0;split(no[x].l,no[y].l,k,op);}else{split(no[x].r,no[y].r,k-no[no[x].l].num,op);}}else{if(no[no[x].r].num==k){no[y].l=no[x].l;no[x].l=0;return;}else if(no[no[x].r].num>k){no[y].l=no[x].l;no[x].l=0;split(no[x].r,no[y].r,k,op);}else{split(no[x].l,no[y].l,k-no[no[x].r].num,op);}}
}
void merge(int &x,int &y,int l,int r)
{if(!x||!y){x|=y;return;}no[x].num+=no[y].num;if(l==r)return;int mid=(l+r)>>1;merge(no[x].l,no[y].l,l,mid);merge(no[x].r,no[y].r,mid+1,r);
}
int query(int x,int l,int r,int pl,int op)
{if(l==r)return l;int mid=(l+r)>>1;//cout<<l<<" "<<r<<endl;if(op==0){if(no[no[x].l].num>=pl)return query(no[x].l,l,mid,pl,op);else return query(no[x].r,mid+1,r,pl-no[no[x].l].num,op);}else{if(no[no[x].r].num>=pl)return query(no[x].r,mid+1,r,pl,op);else return query(no[x].l,l,mid,pl-no[no[x].r].num,op);}
}
set<seg>::iterator it;
int main()
{n=read();m=read();int tmp;for(int i=1;i<=n;i++){tmp=read();insertt(root[i],1,n,tmp);st.insert(seg(i,i));}int op,l,r;while(m--){op=read();l=read();r=read();it=st.lower_bound(seg(l,l));if((*it).l<l){split(root[(*it).l],root[l],l-(*it).l,state[(*it).l]);int L=(*it).l,R=(*it).r;st.erase(it);st.insert(seg(L,l-1));st.insert(seg(l,R));state[l]=state[L];}it=st.lower_bound(seg(r,r));if(it!=st.end()&&(*it).l<=r&&(*it).r>r){split(root[(*it).l],root[r+1],r-(*it).l+1,state[(*it).l]);int L=(*it).l,R=(*it).r;st.erase(it);st.insert(seg(L,r));st.insert(seg(r+1,R));state[r+1]=state[L];}it=st.lower_bound(seg(l,l));it++;while(it!=st.end()&&(*it).r<=r){merge(root[l],root[(*it).l],1,n);it++;}it=st.lower_bound(seg(l,l));while(it!=st.end()&&(*it).r<=r){st.erase(it);it=st.lower_bound(seg(l,l));}st.insert(seg(l,r));state[l]=op;}//cout<<cnt<<endl;tmp=read();it=st.lower_bound(seg(tmp,tmp));//cout<<(*it).l<<" "<<(*it).r<<"\n";//cout<<state[(*it).l]<<"\n";cout<<query(root[(*it).l],1,n,tmp-(*it).l+1,state[(*it).l])<<"\n";}

  另外我总感觉这数据有点弱。

转载于:https://www.cnblogs.com/intwentieth/p/10421230.html

BZOJ4552: [Tjoi2016Heoi2016]排序相关推荐

  1. bzoj千题计划128:bzoj4552: [Tjoi2016Heoi2016]排序

    http://www.lydsy.com/JudgeOnline/problem.php?id=4552 二分答案 把>=mid 的数看做1,<mid 的数看做0 这样升序.降序排列相当于 ...

  2. [BZOJ] 4552: [Tjoi2016Heoi2016]排序

    通过各种手段把序列问题变成01序列问题可以简化问题 这里可以用二分答案,把大于等于的变成1,小于的变成0 然后区间排序就是线段树区间赋值操作啦 复杂度\(O(nlog^2n)\) #include&l ...

  3. bzoj 4552: [Tjoi2016Heoi2016]排序

    Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这个 ...

  4. [Tjoi2016Heoi2016]排序[01序列]

    4552: [Tjoi2016&Heoi2016]排序 Time Limit: 60 Sec  Memory Limit: 256 MB Submit: 994  Solved: 546 [S ...

  5. 【TJOI2016】【bzoj4552】排序(二分答案+线段树01排序)

    problem 给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序 排序分为两种 1:(0,l,r)表示将区间[l,r]的数字升序排序 2:(1,l,r)表示将区间[l,r]的数字降序排序 ...

  6. 线段树 by yyb

    线段树 by yyb Type1 维护特殊信息 1.[洛谷1438]无聊的数列 维护一个数列,两种操作 1.给一段区间加上一个等差数列 2.单点询问值 维护等差数列 不难发现,等差数列可以写成\(ad ...

  7. 【BZOJ4552】【TJOI2016HEOI2016】排序(线段树、二分)

    Description 在2016年,佳媛姐姐喜欢上了数字序列. 因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他. 这个难题是这样子的: 给出一个1到n的全排列,现在 ...

  8. 数据库中自定义排序规则,Mysql中自定义字段排序规则,Oracle中自定义字段排序规则,decode函数的用法,field函数的用法

    数据库中自定义排序 场景:有一张banner表,表中有一个status字段,有0, 1, 2三个状态位,我想要 1,0,2的自定义排序(这里是重点),然后再进行之上对sequence字段进行二次排序( ...

  9. 伍六七带你学算法 进阶篇-排序算法

    给定一个整数数组 nums,将该数组升序排列. 示例 1: 输入:[5,2,3,1] 输出:[1,2,3,5] 示例 2: 输入:[5,1,1,2,0,0] 输出:[0,0,1,1,2,5] 各排序算 ...

最新文章

  1. Linux内核中的platform机制
  2. Java-Runoob-高级教程-实例-数组:01. Java 实例 – 数组排序及元素查找
  3. 产品规划,要考虑哪些方面?
  4. 针对各组项目的改进意见
  5. java web购物车代码_java web开发之购物车功能实现示例代码
  6. 源码与tarball套件管理程序笔记摘录
  7. [html] html标签的属性值是否可以省略引号?为什么?
  8. npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! node-sass@
  9. MMP,我说每年年会我怎么老是中不了奖,原来是这样
  10. @Controller与@RestController有何区别
  11. 【js高三】---js模块模式
  12. 任正非:HR面试不深刻导致大规模进人、走人,耽误人家几年对得起人家吗?...
  13. 实操:SparrowRecsys的首次运行
  14. 学Java看这就完事了!javasocket编程例子
  15. 【2023王道数据结构】【树与二叉树】通过C++实现中序遍历的非递归算法(手动入出栈)C、C++完整实现(可直接运行
  16. ANSA二次开发实战——车身弯扭刚度计算文件自动生成(1)
  17. 利用python读取tomcat中log文件提取出错误日志生成新的文件
  18. 一行代码深度定制你的专属二维码:(amzqr、MyQR制作动态二维码)
  19. tensorflow官方Blog-使用Keras Tuner超参数优化框架 进行超参数调整 ,具体实现版本
  20. Tomcat重启单个服务

热门文章

  1. python中凯撒密码_python实现凯撒密码、凯撒加解密算法
  2. python字符串格式化 说明符顺序_python实践分享:格式化字符串时使用.format方式还是“%”...
  3. 数据预处理之数据描述
  4. Leetcode 208:实现Trie(前缀树)
  5. 社区发现(一)--算法综述
  6. 微服务实现不同登陆_PaaS与IaaS在微服务架构实现方面的6大不同
  7. python爬取b站403_使用Python爬取B站全站视频信息
  8. cpu爆了怎么排查和处理_CPU飙高,系统性能问题如何排查?
  9. docker容器启动与停止命令
  10. presto求时间差