您的位置:首页 > 其它

【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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: