【bzoj4552】【Tjoi2016&Heoi2016】【NOIP2016模拟7.12】排序
2016-07-12 14:38
344 查看
题目
在2016年,佳媛姐姐喜欢上了数字序列。因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他。这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排序分为两种:1:(0,l,r)表示将区间[l,r]的数字升序排序2:(1,l,r)表示将区间[l,r]的数字降序排序最后询问第q 位置上的数字。分析
二分答案,把二分出的ans与原序列比较,小于ans的数改为-1,大于ans的数改为1。
对于输入的每一个修改,用线段树来处理。
最后求出q位上的数是-1还是1,然后接着二分。
#include <cmath> #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <queue> const int maxlongint=2147483647; const int mo=1000000007; const int N=100005; using namespace std; int a ,n,m,re [4],k,ans,lazy[N*5],_0[N*5],_1[N*5]; int down(int v,int mid,int l,int r) { if(lazy[v]==-1) { lazy[v*2+1]=lazy[v*2]=lazy[v]; _0[v*2]=mid-l+1; _0[v*2+1]=r-(mid+1)+1; _1[v*2]=0; _1[v*2+1]=0; } if(lazy[v]==1) { lazy[v*2+1]=lazy[v*2]=lazy[v]; _1[v*2]=mid-l+1; _1[v*2+1]=r-(mid+1)+1; _0[v*2]=0; _0[v*2+1]=0; } lazy[v]=0; } int put(int v,int l,int r,int x,int y) { if(l==r) { if(y==-1) _0[v]=1; else _1[v]=1; return 0; } int mid=(l+r)/2; if(x<=mid) put(v*2,l,mid,x,y); else put(v*2+1,mid+1,r,x,y); _0[v]=_0[v*2]+_0[v*2+1]; _1[v]=_1[v*2]+_1[v*2+1]; } int get(int v,int l,int r,int x,int y) { if(l==x && r==y) { return _1[v]; } int mid=(l+r)/2; down(v,mid,l,r); int o; if(y<=mid) o=get(v*2,l,mid,x,y); else if(x>mid) o=get(v*2+1,mid+1,r,x,y); else o=get(v*2,l,mid,x,mid)+get(v*2+1,mid+1,r,mid+1,y); _0[v]=_0[v*2]+_0[v*2+1]; _1[v]=_1[v*2]+_1[v*2+1]; return o; } int change(int v,int l,int r,int x,int y,int value) { if(y<x) return 0; int mid=(l+r)/2; if(l==x && r==y) { lazy[v]=value; if(value<0) { _0[v]=r-l+1; _1[v]=0; } else { _1[v]=r-l+1; _0[v]=0; } return 0; } down(v,mid,l,r); if(y<=mid) change(v*2,l,mid,x,y,value); else if(x>mid) change(v*2+1,mid+1,r,x,y,value); else change(v*2,l,mid,x,mid,value),change(v*2+1,mid+1,r,mid+1,y,value); _0[v]=_0[v*2]+_0[v*2+1]; _1[v]=_1[v*2]+_1[v*2+1]; } int find(int v,int l,int r,int x) { if(l==r) { return _0[v]; } int mid=(l+r)/2; down(v,mid,l,r); int o; if(x<=mid) o=find(v*2,l,mid,x); else o=find(v*2+1,mid+1,r,x); _0[v]=_0[v*2]+_0[v*2+1]; _1[v]=_1[v*2]+_1[v*2+1]; return o; } bool check(int x) { memset(lazy,0,sizeof(lazy)); memset(_0,0,sizeof(_0)); memset(_1,0,sizeof(_1)); for(int i=1;i<=n;i++) { int g=a[i]<=x?-1:1; put(1,1,n,i,g); } for(int i=1;i<=m;i++) { int p1=get(1,1,n,re[i][2],re[i][3]); if(!re[i][1]) { change(1,1,n,re[i][2],re[i][3]-p1,-1); change(1,1,n,re[i][3]-p1+1,re[i][3],1); } else { change(1,1,n,re[i][2],re[i][2]+p1-1,1); change(1,1,n,re[i][2]+p1,re[i][3],-1); } } if(find(1,1,n,k)) return true; else return false; } 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",&re[i][1],&re[i][2],&re[i][3]); } scanf("%d",&k); int l=1,r=n; while(l<r) { int mid=(l+r)/2; if(check(mid)) { r=mid; } else { l=mid+1; } } printf("%d",l); }
相关文章推荐
- Reverse Bits
- 7.12 noip2103提高组复赛day2
- RabbitMQ消息队列(二):”Hello, World“
- Java常用代码工具类相关
- Trilateration三边测量定位算法
- 刚刚提取了金山毒霸的[垃圾清理] 和 [隐私清理], 分享方法,大家可以自己试一下
- Google App Engine的app.yaml详细说明
- Android绘制音乐播放器示波器
- java I/O流详解
- java加载properties文件的六种基本方式
- 数值的整数次方代码实现
- {小结}2016.07.12【初中部 NOIP提高组 】模拟赛B
- Ubuntu 上进行VNCserver的搭建
- C语言入门(十七)指针概念
- 生成1到300个数字的方法
- Java 中的锁——Lock接口
- Objective-C Runtime
- MyBatis学习4---使用MyBatis_Generator生成Dto、Dao、Mapping
- 调用C底层进行线程创建
- socket编程(九)listen()