【JZOJ 4605】【BZOJ 4552】排序
2016-07-11 17:03
465 查看
Description
在2016年,佳媛姐姐喜欢上了数字序列。因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他。这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排
序分为两种:1:(0,l,r)表示将区间[l,r]的数字升序排序2:(1,l,r)表示将区间[l,r]的数字降序排序最后询问第q
位置上的数字。
Solution
二分答案,大于mid的数改成1,小于等于的改成0,于是每次的改变就变成了用线段树来维护:查询当前区间的1的个数,
最后查询一下那一位,就可以确认往左还是往右
Code
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #define fo(i,a,b) for(int i=a;i<=b;i++) #define merge(e,q,w) b[e]=b[q]+b[w] using namespace std; const int N=100500,maxlongint=2107483647; int read(int &n) { char ch=' ';int q=0,w=1; for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar()); if(ch=='-')w=-1,ch=getchar(); for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n; } int n,m,m1,ans,a ; int b[3*N],la[N*3]; int sc [3]; void build(int l,int r,int e,int l1) { if(l==r){b[e]=(a[l]>l1);return;} int t=(l+r)/2; build(l,t,e*2,l1),build(t+1,r,e*2+1,l1); merge(e,e*2,e*2+1); } void doit(int l,int r,int e) { if(la[e]==-1)return; b[e]=la[e]*(r-l+1); if(l!=r)la[e*2]=la[e],la[e*2+1]=la[e]; la[e]=-1; } int find(int l,int r,int e,int l1,int r1) { doit(l,r,e); if(l==l1&&r==r1)return b[e]; int t=(l+r)/2; if(r1<=t)return find(l,t,e*2,l1,r1); else if(t<l1)return find(t+1,r,e*2+1,l1,r1); else return find(l,t,e*2,l1,t)+find(t+1,r,e*2+1,t+1,r1); } void change(int l,int r,int e,int l1,int r1,int l2) { if(l1>r1)return; doit(l,r,e); if(l==l1&&r==r1){la[e]=l2;doit(l,r,e);return;} int t=(l+r)/2; if(r1<=t)change(l,t,e*2,l1,r1,l2),doit(t+1,r,e*2+1); else if(t<l1)doit(l,t,e*2),change(t+1,r,e*2+1,l1,r1,l2); else change(l,t,e*2,l1,t,l2),change(t+1,r,e*2+1,t+1,r1,l2); merge(e,e*2,e*2+1); } int main() { int q,w,e; scanf("%d%d",&n,&m); fo(i,1,n)read(a[i]); fo(i,1,m)fo(j,0,2)read(sc[i][j]); read(m1); int l=1,r=n; while(l<r) { int t=(l+r)/2; memset(la,255,sizeof(la)); build(1,n,1,t); fo(i,1,m) { q=find(1,n,1,sc[i][1],sc[i][2]); if(!sc[i][0]) { change(1,n,1,sc[i][1],sc[i][2]-q,0); change(1,n,1,sc[i][2]-q+1,sc[i][2],1); }else { change(1,n,1,sc[i][1],sc[i][1]-1+q,1); change(1,n,1,sc[i][1]+q,sc[i][2],0); } } if(find(1,n,1,m1,m1))l=t+1; else r=t; } printf("%d\n",l); return 0; }
相关文章推荐
- <s:if></>与EL表达式
- spring security 一个验证码登录例子
- 格式化日期操作(一)
- mongodb3.0副本集搭建补充~~非admin数据库的用户权限
- Android Studio调试方法
- OpenGL入门记录-glut库链接错误 LNK2019
- Linux kernel mm 异常处理 on arm
- 肇事车辆
- FragmentActivity和Activity的具体区别在哪里
- Java Set 排序
- 加速Android Studio/Gradle构建
- github的基本使用
- express 4中间件迁移
- 【TJOI & HEOI 2016】【JZOJ 4605】 【BZOJ 4552】排序
- java的文件操作(2)
- 计蒜客 菜鸟物流的运输网络
- typedef
- android整合两个bitmap
- cxf 实例解读
- javaScript的DOM节点处理