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 ( 1\leq n, q \leq 2*10^5, 0\leq x\leq 10^9)n,q,x(1n,q2105,0x109)表示元素的个数和询问的个数。

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

接下来qq行,每行三个正整数p, l, r (1\leq p\leq 3), 1\leq l\leq r\leq 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

猜你喜欢

转载自www.cnblogs.com/Fighting-sh/p/10318996.html