首页 写随笔

cdcq(本博客废弃!现用博客:https://www.cnblogs.com/cdcq/)

本博客废弃!现用博客:https://www.cnblogs.com/cdcq/

导航

【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 }
View Code

 

posted on 2017-03-16 10:54  cdcq_old  阅读(240)  评论(0编辑  收藏  举报