【BZOJ4552】【TJOI2016】【HEOI2016】排序
经验还是不够……
原题:
在2016年,佳媛姐姐喜欢上了数字序列。因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题
,需要你来帮助他。这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排
序分为两种:1:(0,l,r)表示将区间[l,r]的数字升序排序2:(1,l,r)表示将区间[l,r]的数字降序排序最后询问第q
位置上的数字。
1 <= n, m <= 10^5
没思路,看题解
这个本应不看题解的,但是急于刷AC数就看了,果然还是要放下每日6题的任务?
正解是二分一个值,把序列中<=它的设为1,大于的设为0,然后建线段树
每次排序先查询区间中有多少个1,然后以1的个数为分界线,根据升序或降序把左边和右边分别buff成1或0
这样一番操作之后第x的位置的值就表示位置x上的数和当前二分的数的大小关系
然后根据这个二分就行了
暂时不能把这个方法延伸到更多的地方去,需要再思考
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 const int oo=168430090; 8 int rd(){int z=0,mk=1; char ch=getchar(); 9 while(ch<'0'||ch>'9'){if(ch=='-')mk=-1; ch=getchar();} 10 while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0'; ch=getchar();} 11 return z*mk; 12 } 13 struct dcd{int mk,x,y;}b[110000]; 14 int n,m,a[110000],qst; 15 int v[410000],dt[410000]; 16 int mn=oo,mx=0; 17 void gtsgmttr(int x,int y,int l,int r){ 18 dt[x]=-1,v[x]=0; 19 if(l==r){ v[x]=(y>=a[l]); return ;} 20 int md=(l+r)>>1; 21 gtsgmttr(x<<1,y,l,md),gtsgmttr(x<<1|1,y,md+1,r); 22 v[x]=v[x<<1]+v[x<<1|1]; 23 } 24 void pshd(int x,int l,int r,int md){ 25 if(dt[x]==-1) return ; 26 v[x<<1]=(md-l+1)*dt[x],v[x<<1|1]=(r-md)*dt[x]; 27 dt[x<<1]=dt[x<<1|1]=dt[x]; 28 dt[x]=-1; 29 } 30 void mdf(int x,int l,int r,int z,int ll,int rr){ 31 if(l>r) return ; 32 if(l==ll && r==rr){ v[x]=(r-l+1)*z,dt[x]=z; return ;} 33 int md=(ll+rr)>>1; pshd(x,ll,rr,md); 34 if(l<=md && r>md) mdf(x<<1,l,md,z,ll,md),mdf(x<<1|1,md+1,r,z,md+1,rr); 35 else if(r<=md) mdf(x<<1,l,r,z,ll,md); 36 else mdf(x<<1|1,l,r,z,md+1,rr); 37 v[x]=v[x<<1]+v[x<<1|1]; 38 } 39 int qr(int x,int l,int r,int ll,int rr){ 40 if(l==ll && r==rr) return v[x]; 41 int md=(ll+rr)>>1; pshd(x,ll,rr,md); 42 if(l<=md && r>md) return qr(x<<1,l,md,ll,md)+qr(x<<1|1,md+1,r,md+1,rr); 43 else if(r<=md) return qr(x<<1,l,r,ll,md); 44 else return qr(x<<1|1,l,r,md+1,rr); 45 } 46 int sch(int x,int y,int ll,int rr){ 47 if(y==ll && y==rr) return v[x]; 48 int md=(ll+rr)>>1; pshd(x,ll,rr,md); 49 if(y<=md) return sch(x<<1,y,ll,md); 50 else return sch(x<<1|1,y,md+1,rr); 51 } 52 bool chck(int x){ 53 gtsgmttr(1,x,1,n); 54 //cout<<x<<endl; 55 //for(int i=1;i<=n;++i) printf("%d ",sch(1,i,1,n)); 56 //cout<<endl; 57 int bwl; 58 for(int i=1;i<=m;++i){ 59 bwl=qr(1,b[i].x,b[i].y,1,n); 60 /*if(b[i].mk) mdf(1,b[i].x,b[i].x+bwl-1,0,1,n),mdf(1,b[i].x+bwl,b[i].y,1,1,n); 61 else mdf(1,b[i].x,b[i].y-bwl,1,1,n),mdf(1,b[i].y-bwl+1,b[i].y,0,1,n);*/ 62 if(b[i].mk) mdf(1,b[i].x,b[i].y-bwl,0,1,n),mdf(1,b[i].y-bwl+1,b[i].y,1,1,n); 63 else mdf(1,b[i].x,b[i].x+bwl-1,1,1,n),mdf(1,b[i].x+bwl,b[i].y,0,1,n); 64 //for(int j=1;j<=n;++j) printf("%d ",sch(1,j,1,n)); 65 //cout<<endl; 66 } 67 return sch(1,qst,1,n); 68 } 69 int bnrsch(){ 70 int l=mn,r=mx,md; 71 while(l+1<r) md=(l+r)>>1,(chck(md) ? r : l)=md; 72 return chck(l) ? l : r; 73 } 74 int main(){//freopen("ddd.in","r",stdin); 75 cin>>n>>m; 76 for(int i=1;i<=n;++i) a[i]=rd(),mn=min(mn,a[i]),mx=max(mx,a[i]); 77 for(int i=1;i<=m;++i) b[i].mk=rd(),b[i].x=rd(),b[i].y=rd(); 78 cin>>qst; 79 cout<<bnrsch()<<endl; 80 return 0; 81 }