BZOJ 4552 [Tjoi2016&Heoi2016]排序 线段树的分裂和合并
https://www.lydsy.com/JudgeOnline/problem.php?id=4552
https://blog.csdn.net/zawedx/article/details/51818475
区间排序,这道题需要写两个线段树还要维护一个链表,有些细节,对我目前的代码能力来说有点算是码农题,但是理解思路之后调试起来出乎意料地简单。
这个写法的复杂度据说是nlogn的,我也不是很会算,反正能过就行(bushi)。
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<cmath>
- #include<queue>
- using namespace std;
- #define LL long long
- #define lc x*2
- #define rc x*2+1
- #define mid (l+r)/2
- const int maxn=;
- const int maxm=;
- int n,m;
- struct sgtree{
- int rn[maxm];
- void updata(int x){rn[x]=(rn[rc]?rn[rc]:rn[lc]);}
- void ins(int x,int l,int r,int k,int v){
- if(l==r){rn[x]=v;return;}
- if(k>mid)ins(rc,mid+,r,k,v);
- else ins(lc,l,mid,k,v);
- updata(x);
- }
- int ask(int x,int l,int r,int k){
- if(!rn[x])return ;
- if(l==r)return rn[x];
- int zz=;
- if(mid<k)zz=ask(rc,mid+,r,k);
- if(zz)return zz;
- if(mid<=k)return rn[lc];
- else return ask(lc,l,mid,k);
- }
- }e;
- struct nod{ int l,r,tp,nxt; }c[maxm];
- struct node{ int l,r,sum; }t[maxm];
- queue<int>q;
- inline int newp(){
- int z=q.front();q.pop();
- return z;
- }
- inline void delp(int x){
- q.push(x);t[x]=t[];
- }
- void build(int x,int l,int r,int k){
- t[x].sum=;
- if(l==r)return;
- if(k>mid)build(t[x].r=newp(),mid+,r,k);
- else build(t[x].l=newp(),l,mid,k);
- }
- int mmerg(int x,int y){
- if((!x)||(!y))return x+y;
- t[x].l=mmerg(t[x].l,t[y].l);
- t[x].r=mmerg(t[x].r,t[y].r);
- t[x].sum=t[x].sum+t[y].sum;
- delp(y); return x;
- }
- void mspli(int x,int y,int k){
- int z=t[t[x].l].sum;
- if(z<k)mspli(t[x].r,t[y].r=newp(),k-z);else swap(t[x].r,t[y].r);
- if(z>k)mspli(t[x].l,t[y].l=newp(),k);
- t[y].sum=t[x].sum-k;
- t[x].sum=k;
- }
- int mask(int x,int l,int r,int k){
- if(l==r)return l;
- int z=t[t[x].l].sum;
- if(k>z)return mask(t[x].r,mid+,r,k-z);
- else return mask(t[x].l,l,mid,k);
- }
- int main(){
- int x,v,op,l,r;
- for(int i=;i<=maxm-;++i)q.push(i);
- scanf("%d%d",&n,&m);
- for(int i=,las=maxm-;i<=n;++i,las=x){
- scanf("%d",&v);
- c[las].nxt=x=newp();
- c[x]=(nod){i,i,,};
- e.ins(,,n,i,x);build(x,,n,v);
- }
- for(int i=;i<=m;++i){
- scanf("%d%d%d",&op,&l,&r);
- /*for(x=1;x<=n;++x){
- int w=e.ask(1,1,n,x);
- //cout<<w<<' ';
- if(c[w].tp)printf("%d ",mask(w,1,n,c[w].r-x+1));
- else printf("%d ",mask(w,1,n,x-c[w].l+1));
- }printf("\n");*/
- int lef=e.ask(,,n,l),rig,now,nxt;
- if(l==c[lef].l){
- rig=newp();
- swap(t[rig],t[lef]); swap(c[rig],c[lef]);
- c[now=lef]=(nod){l,r,op,rig};
- }
- else{
- c[now=newp()]=(nod){l,r,op,rig=newp()};
- if(!c[lef].tp) mspli(lef,rig,l-c[lef].l);
- else {mspli(lef,rig,c[lef].r-l+);swap(t[lef],t[rig]);}
- c[rig]=c[lef];c[rig].l=l;
- c[lef].r=l-;c[lef].nxt=now;
- }
- for(nxt=rig;nxt&&r>=c[nxt].r;){
- //cout<<t[nxt].sum<<endl;
- mmerg(now,nxt);e.ins(,,n,c[nxt].l,);
- int qq=nxt;nxt=c[nxt].nxt;c[qq]=c[];
- }
- c[now].nxt=nxt;
- if(nxt!=&&c[nxt].l<=r){
- e.ins(,,n,c[nxt].l,);
- int zz=newp();
- if(!c[nxt].tp) {mspli(nxt,zz,r-c[nxt].l+);swap(t[nxt],t[zz]);}
- else mspli(nxt,zz,c[nxt].r-r);
- mmerg(now,zz);
- c[nxt].l=r+;
- e.ins(,,n,r+,nxt);
- }
- e.ins(,,n,l,now);
- }
- /*for(x=1;x<=n;++x){
- int w=e.ask(1,1,n,x);
- //cout<<w<<' ';
- if(c[w].tp)printf("%d ",mask(w,1,n,c[w].r-x+1));
- else printf("%d ",mask(w,1,n,x-c[w].l+1));
- }printf("\n");*/
- scanf("%d",&x);
- int w=e.ask(,,n,x);
- if(c[w].tp)printf("%d\n",mask(w,,n,c[w].r-x+));
- else printf("%d\n",mask(w,,n,x-c[w].l+));
- return ;
- }
BZOJ 4552 [Tjoi2016&Heoi2016]排序 线段树的分裂和合并的更多相关文章
- BZOJ 4552: [Tjoi2016&Heoi2016]排序 线段树 二分
目录 此代码是个假代码,只能糊弄luogu,以后再改,路过大佬也可以帮一下辣 update 10.6 此代码是个假代码,只能糊弄luogu,以后再改,路过大佬也可以帮一下辣 /* //fang zhi ...
- BZOJ 4552 [Tjoi2016&Heoi2016]排序 ——线段树 二分答案
听说是BC原题. 好题,二分答案变成01序列,就可以方便的用线段树维护了. 然后就是区间查询和覆盖了. #include <map> #include <cmath> #inc ...
- BZOJ 4552: [Tjoi2016&Heoi2016]排序
4552: [Tjoi2016&Heoi2016]排序 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 579 Solved: 322[Sub ...
- bzoj 4552 [Tjoi2016&Heoi2016]排序 (二分答案 线段树)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4552 题意: 给你一个1-n的全排列,m次操作,操作由两种:1.将[l,r]升序排序,2 ...
- BZOJ 4552 [Tjoi2016&Heoi2016]排序 | 二分答案 线段树
题目链接 题面 题目描述 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这 ...
- bzoj 4552: [Tjoi2016&Heoi2016]排序——二分+线段树
Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题 ,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这 ...
- bzoj 4552: [Tjoi2016&Heoi2016]排序【二分+线段树】
二分值mid,然后把>=mid的赋值为1,其他赋值为0,每次排序就是算出区间内01的个数,然后分别把0和1放到连续的一段内,这些都可以用线段树来维护 二分的判断条件是操作完之后q位置上是否为1 ...
- BZOJ4552:[TJOI2016&HEOI2016]排序(线段树,二分)
Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他. 这个难题是这样子的:给出一个1到n的全排列,现在对这 ...
- bzoj 4552 [Tjoi2016&Heoi2016]排序——二分答案
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4552 二分答案,把 >= mid 的设成1.< mid 的设成0,之后排序就变成 ...
随机推荐
- Dubbo服务超时
服务消费者引用服务提供者的服务时可能由于网络原因导致长时间未返回相应,此时大量的线程将会阻塞,引起性能下降等问题.可以通过引入服务超时来解决该问题 服务超时指服务在给定的时间内未返回相应将立即终止该请 ...
- pytorch官网上两个例程
caffe用起来太笨重了,最近转到pytorch,用起来实在不要太方便,上手也非常快,这里贴一下pytorch官网上的两个小例程,掌握一下它的用法: 例程一:利用nn 这个module构建网络,实现 ...
- Linux MMC framework2:基本组件之host
声明:本文很多内容和思路参考了http://www.wowotech.net/comm/mmc_host_driver.html,对原作者表示感谢! 1.前言 本文是Linux MMC framewo ...
- css 悬浮框
<style> .xfk { display: block; position: fixed; top: 150px; lef ...
- VS C# xamarin 开发android 调试正常 发布分发后运行闪退出错
我强烈推荐大家如果不是很有必要就不要引用一些.NET STD的库,比如json库newtonsoft.JSON,直接引用官方的system.Json就足够了,否则会导致体积变得巨大 好了废话不多说,这 ...
- wordpress安装主题时提示无法创建目录
直接上解决办法: 找到wp-content文件夹(我的是在/home/wwwroot/default/wp-cotent) 首先给wp-content这个文件夹一个权限 chmod -R 775 wp ...
- iOS 中的Certificate,Provisioning Profile 的一些注意 (不断完善中)
注册apple id 有1年多了,这些概念还是模模糊糊的,决定在这里总结一下. 请参阅官方文档 App Distribution Guide code singing的作用如下: Code signi ...
- vue系列之项目结构
参考地址:链接 build webpack配置相关 config webpack配置相关 node_modules npm install 安装的依赖代码库 src 存放项目源码 static 存 ...
- 测试开发之前端——No6.HTML5中的键盘事件
键盘事件 由键盘触发的事件. 适用于所有 HTML 5 元素: 属性 值 描述 onkeydown script 当按下按键时运行脚本 onkeypress script 当按下并松开按键时运行脚本 ...
- vue构建项目全过程
1.node版本请更新到6.9.X版本以上,不然npm依赖会出问题 2.命令行里运行npm install --global vue-cli 3.npm install --global webpac ...