• Sorting(好题)


    Sorting

    https://www.zhixincode.com/contest/21/problem/I?problem_id=324

    题目描述

     

    你有一个数列a_1, a_2, dots, a_na1,a2,,an,你要模拟一个类似于快速排序的过程。有一个固定的数字xx。

    你要支持三种操作:

    • 询问区间[l, r][l,r]之间的元素的和,也就是sum_{i=l}^r a_ii=lrai
    • 对区间[l,r][l,r]进行操作,也就是说你把区间中所有的数字拿出来,然后把小于等于xx的数字按顺序放在左边,把大于xx的数字按顺序放在右边,把这些数字接起来,放回到数列中。比如说x=3x=3,你的区间里的数字是1,5,3,2,41,5,3,2,4,那么操作完之后区间里面的数字变为1,3,2,5,41,3,2,5,4。
    • 对区间[l,r][l,r]进行操作,也就是说你把区间中所有的数字拿出来,然后把大于xx的数字按顺序放在左边,把小于等于xx的数字按顺序放在右边,把这些数字接起来,放回到数列中。
     
     

    输入描述

     

    第一行三个整数n, q, x ( 1leq n, q leq 2*10^5, 0leq xleq 10^9)n,q,x(1n,q2105,0x109)表示元素的个数和询问的个数。

    接下来一行nn个整数a_1, a_2, dots, a_n(1leq a_ileq 10^9)a1,a2,,an(1ai109)。

    接下来qq行,每行三个正整数p, l, r (1leq pleq 3), 1leq lleq rleq np,l,r(1p3),1lrn表示操作种类和区间。

    输出描述

     

    对于每个第一种操作,输出一行,表示答案。

    样例输入 1 

    5 9 3
    1 5 3 2 4
    1 1 5
    2 1 5
    1 1 1
    1 2 2
    1 3 3
    1 4 4
    1 5 5
    3 3 5
    1 1 4
    

    样例输出 1

    15
    1
    3
    2
    5
    4
    15

    首先,排序后小于等于x和大于x的数字的相对顺序是不变的,所以我们可以用0和1分别代替小于等于x和大于x的值。

    先记录下小于等于x的数字和大于x的数字的前缀和,然后当区间修改的时候,我们就可以用前缀和来计算区间的值

    区间修改的过程:当p==2时,把区间前半部分赋值为0,后半部分赋值为1,p==3时相反

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 #define lson l,mid,rt<<1
      5 #define rson mid+1,r,rt<<1|1
      6 #define maxn 200005
      7 
      8 int n,q;
      9 ll x;
     10 
     11 int tree[maxn<<3],lazy[maxn<<3];
     12 ll a[maxn];
     13 
     14 //tree中记录了1的个数 
     15 
     16 void push_up(int rt){
     17     tree[rt]=tree[rt<<1]+tree[rt<<1|1];
     18 }
     19 
     20 void build(int l,int r,int rt){
     21     lazy[rt]=-1;
     22     if(l==r){
     23         if(a[l]<=x) tree[rt]=0;
     24         else tree[rt]=1;
     25         return;
     26     }
     27     int mid=l+r>>1;
     28     build(lson);
     29     build(rson);
     30     push_up(rt);
     31 }
     32 
     33 void push_down(int len,int rt){
     34     if(lazy[rt]!=-1){
     35         if(lazy[rt]==0){
     36             lazy[rt<<1]=0;
     37             lazy[rt<<1|1]=0;
     38             tree[rt<<1]=0;
     39             tree[rt<<1|1]=0;
     40         }
     41         else{
     42             lazy[rt<<1]=1;
     43             lazy[rt<<1|1]=1;
     44             tree[rt<<1]=len-len/2;
     45             tree[rt<<1|1]=len/2;
     46         }
     47         lazy[rt]=-1;
     48     }
     49 }
     50 
     51 //区间置0和置1 
     52 void add(int L,int R,int v,int l,int r,int rt){
     53     if(L<=l&&R>=r){
     54         if(v==0) tree[rt]=0;
     55         else tree[rt]=r-l+1;
     56         lazy[rt]=v;
     57         push_down(r-l+1,rt);
     58         return;
     59     }
     60     push_down(r-l+1,rt); 
     61     int mid=l+r>>1;
     62     if(L<=mid) add(L,R,v,lson);
     63     if(R>mid) add(L,R,v,rson);
     64     push_up(rt);
     65 } 
     66 
     67 int query(int L,int R,int l,int r,int rt){///查询在L前面1的数量 
     68     if(L<=l&&R>=r){
     69         return tree[rt];
     70     }
     71     push_down(r-l+1,rt);
     72     int mid=l+r>>1;
     73     int ans=0;
     74     if(L<=mid) ans+=query(L,R,lson);
     75     if(R>mid) ans+=query(L,R,rson);
     76     push_up(rt);
     77     return ans;
     78 }
     79 
     80 ll small[maxn],big[maxn];
     81 
     82 int main(){
     83     std::ios::sync_with_stdio(false);
     84     cin>>n>>q>>x;
     85     int s_co=1,b_co=1;
     86     for(int i=1;i<=n;i++){
     87         cin>>a[i];
     88         if(a[i]<=x) small[s_co]=small[s_co-1]+a[i],s_co++;
     89         else big[b_co]=big[b_co-1]+a[i],b_co++;
     90     }
     91     build(1,n,1);
     92     int p,l,r;
     93     for(int i=1;i<=q;i++){
     94         cin>>p>>l>>r;
     95         if(p==1){
     96             int one1,one2,one,zero1,zero2,zero;
     97             one1=query(1,r,1,n,1);
     98             if(1>l-1) one2=0;
     99             else one2=query(1,l-1,1,n,1);
    100             zero1=r-one1;
    101             if(1>l-1) zero2=0;
    102             else zero2=l-1-one2;
    103             cout<<small[zero1]-small[zero2]+big[one1]-big[one2]<<endl;
    104         }
    105         else if(p==2){
    106             int one=query(l,r,1,n,1);
    107             int zero=r-l+1-one;
    108             if(l<=l+zero-1) add(l,l+zero-1,0,1,n,1);
    109             add(l+zero,r,1,1,n,1); 
    110         }
    111         else{
    112             int one=query(l,r,1,n,1);
    113             int zero=r-l+1-one;
    114             if(l<=l+one-1) add(l,l+one-1,1,1,n,1);
    115             add(l+one,r,0,1,n,1); 
    116         }
    117     }
    118 } 
    View Code
  • 相关阅读:
    计算机科学导论 笔记四 【机械工业出版社-原书第二版】
    计算机科学导论 笔记三(2) 【机械工业出版社-原书第二版】
    计算机科学导论 笔记三(1) 【机械工业出版社-原书第二版】
    Maya入门笔记一 用户界面
    大数据分析技术【超星尔雅课后题】
    DNS服务 实验
    区分"研发支出"、"开发支出"、"研发费用"
    关于stata中我们常用到的对数化处理
    线性回归——Lasso回归和岭回归
    ROC曲线
  • 原文地址:https://www.cnblogs.com/Fighting-sh/p/10318996.html
Copyright © 2020-2023  润新知