ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【2021蓝桥杯省赛】双向排序

2021-09-23 11:03:26  阅读:1058  来源: 互联网

标签:rt sz pre int 蓝桥 修改 2021 省赛 aqi


3419. 双向排序

给定序列 (a1,a2,⋅⋅⋅,an)=(1,2,⋅⋅⋅,n),即 ai=i。

小蓝将对这个序列进行 m 次操作,每次可能是将 a1,a2,⋅⋅⋅,aqi 降序排列,或者将 aqi,aqi+1,⋅⋅⋅,an 升序排列。

请求出操作完成后的序列。

输入格式
输入的第一行包含两个整数 n,m,分别表示序列的长度和操作次数。

接下来 m 行描述对序列的操作,其中第 i 行包含两个整数 pi,qi 表示操作类型和参数。当 pi=0 时,表示将 a1,a2,⋅⋅⋅,aqi 降序排列;当 pi=1 时,表示将 aqi,aqi+1,⋅⋅⋅,an 升序排列。

输出格式
输出一行,包含 n 个整数,相邻的整数之间使用一个空格分隔,表示操作完成后的序列。

数据范围
对于 30% 的评测用例,n,m≤1000;
对于 60% 的评测用例,n,m≤5000;
对于所有评测用例,1≤n,m≤105,0≤pi≤1,1≤qi≤n。

输入样例:
3 3
0 3
1 2
0 2
输出样例:
3 1 2
样例解释
原数列为 (1,2,3)。

第 1 步后为 (3,2,1)。

第 2 步后为 (3,1,2)。

第 3 步后为 (3,1,2)。与第 2 步操作后相同,因为前两个数已经是降序了。

正解是思维+栈
这里剽窃一下别人的线段树写法:

  • 整一个pre做分界点,0修改小于p 1修改大于等于p时候不用修改,跳过。
  • 可以发现不论是0修改还是1修改都是修改对立区间最小的几个数‘
  • 在线段树上修改除了已有还需要修改的sz个最小的数(也就是在树上左边的区间)
struct SegTree{
   int val,lazy;
}segtree[N<<2];
void push_up(int rt){
   segtree[rt].val = segtree[rt<<1].val + segtree[rt<<1|1].val;
}
void push_down(int l,int r,int rt){
   if(segtree[rt].lazy == -1) return ;
   int mid =l+r>>1;
   segtree[rt<<1].lazy=segtree[rt<<1|1].lazy = segtree[rt].lazy;
   segtree[rt<<1].val = segtree[rt].lazy*(mid-l+1);
   segtree[rt<<1|1].val = segtree[rt].lazy*(r-mid);
   segtree[rt].lazy = -1;
}
void build(int l,int r,int rt){
   segtree[rt].lazy = -1;
   if(l == r) { segtree[rt].val = 1; return ; }
   int mid =l+r>>1;
   build(l,mid,rt<<1); build(mid+1,r,rt<<1|1);
   push_up(rt);
}
void update1(int sz,int l,int r,int rt){
   int cnt = r-l+1-segtree[rt].val;
   if(cnt<=sz) {
       segtree[rt].val = r-l+1;
       segtree[rt].lazy = 1;
       return ;
   }
   push_down(l,r,rt);
   int mid =l+r>>1;
   int cnt1 = mid-l+1-segtree[rt<<1].val;
   if(cnt1>=sz){
       update1(sz,l,mid,rt<<1);
   }
   else{
       update1(cnt1,l,mid,rt<<1);
       update1(sz-cnt1,mid+1,r,rt<<1|1);
   }
   push_up(rt);
}
void update0(int sz,int l,int r,int rt){
   int cnt = segtree[rt].val;
   if(cnt<=sz) {
       segtree[rt].val = 0;
       segtree[rt].lazy = 0;
       return ;
   }
   push_down(l,r,rt);
   int mid =l+r>>1;
   int cnt1 = segtree[rt<<1].val;
   if(cnt1>=sz){
       update0(sz,l,mid,rt<<1);
   }
   else{
       update0(cnt1,l,mid,rt<<1);
       update0(sz-cnt1,mid+1,r,rt<<1|1);
   }
   push_up(rt);
}
int query(int a,int l,int r,int rt){

   if(l==r) return segtree[rt].val;
   push_down(l,r,rt);
   int mid = l+r>>1;
   if(a<=mid) query(a,l,mid,rt<<1);
   else  query(a,mid+1,r,rt<<1|1);
}
vector<int>ve0; vector<int>ve1;
int main(){
   int n,m,opt,x;
   cin>>n>>m;
   int pre =1;
   build(1,n,1);
   while(m--){
       cin>>opt>>x;
       if(opt){//只修改在对立区最小的那几个数
           if(x>=pre) continue;
           update1(pre-x,1,n,1);
           pre= x;
       }else{
           if(x<pre) continue;
           update0(x-pre+1,1,n,1);
           pre = x+1;
       }
   }
   for(int i=1;i<=n;i++){if(query(i,1,n,1)) ve1.push_back(i);
       else ve0.push_back(i);}
   for(int i = ve0.size()-1;i>=0;i--){
       cout<<ve0[i]<<" ";
   }
   for(auto i:ve1){
       cout<<i<<" ";
   }
   cout<<endl;
   return 0;
}

标签:rt,sz,pre,int,蓝桥,修改,2021,省赛,aqi
来源: https://www.cnblogs.com/muscletear/p/15323206.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有