Sorting (线段树+思维) ccpcwannafly

Sorting

   

0.00%

提交人数:3

通过人数:0

题目描述

 

你有一个数列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
13






发现对题目总的操作,小于等于x的树的相对顺序不会改版,
从前也讲过把操作序列转变成01序列的题,然后这个题也是。
小于等于的变成0,大的变成1
翻转就是 统计区间内又几个1,几个0,前面的一段赋值为0,后面的一段赋值为1,
求和就是,单开两个数组按顺序存两种树,求前缀和,每次作差求答案。




  1 #include<bits/stdc++.h>
  2 #define CLR(a,b) memset(a,b,sizeof(a))
  3 using namespace std;
  4 typedef long long ll;
  5 const int maxn=200010;
  6 const int inf=0x3f3f3f3f;
  7 ll a[maxn];
  8 struct node{
  9     ll sum,lazy;
 10 }tr[maxn<<2];
 11 int n,q,pa,pb;
 12 ll x,prea[maxn],preb[maxn]; 
 13 void init(){
 14     pa=0,pb=0;
 15 }
 16 void build(int o,int l,int r){
 17     if(l==r){
 18         tr[o].sum=a[l];
 19         tr[o].lazy=-1;
 20         return ;
 21     }
 22     int mid=(l+r)>>1;
 23     build(o<<1,l,mid);
 24     build((o<<1)|1,mid+1,r);
 25     tr[o].sum=tr[o<<1].sum+tr[(o<<1)|1].sum;
 26     tr[o].lazy=-1;
 27 }
 28 void pushup(int o){
 29     tr[o].sum=tr[o<<1].sum+tr[o<<1|1].sum;
 30 }
 31 void pushdown(int o,int l,int r){
 32     if(tr[o].lazy!=-1){
 33         tr[o<<1].lazy=tr[o].lazy;
 34         tr[o<<1|1].lazy=tr[o].lazy;
 35         int mid=(l+r)>>1;
 36         tr[o<<1].sum=tr[o].lazy*(mid-l+1);
 37         tr[o<<1|1].sum=tr[o].lazy*(r-mid);
 38         tr[o].lazy=-1;
 39     }
 40 }
 41 void update(int o,int l,int r,int ql,int qr,ll val){
 42     if(ql<=l&&r<=qr){
 43         tr[o].lazy=val;
 44         tr[o].sum=val*(r-l+1);
 45         return;
 46     }
 47     pushdown(o,l,r);
 48     int mid=l+((r-l)>>1);
 49     if(ql<=mid)update(o<<1,l,mid,ql,qr,val);
 50     if(qr>=mid+1)update(o<<1|1,mid+1,r,ql,qr,val);
 51     pushup(o);
 52 }
 53 ll query(int o,int l,int r,int ql,int qr){
 54     if(ql<=l&&qr>=r)return tr[o].sum;
 55     pushdown(o,l,r);
 56     int mid=(l+r)>>1;
 57     ll ans=0;
 58     if(ql<=mid)ans=query(o<<1,l,mid,ql,qr);
 59     if(qr>=mid+1)ans+=query(o<<1|1,mid+1,r,ql,qr);
 60     return ans;
 61 }
 62 int op,u,v;
 63 int main(){
 64     while(cin>>n>>q>>x){
 65         init();
 66         for(int i=1;i<=n;i++)
 67         {
 68             scanf("%lld",&a[i]);
 69             if(a[i]<=x){
 70                 prea[++pa]=a[i];
 71                 prea[pa]+=prea[pa-1];
 72                 a[i]=0;
 73             }else{
 74                 preb[++pb]=a[i];
 75                 preb[pb]+=preb[pb-1];
 76                 a[i]=1;
 77             }
 78         }
 79         build(1,1,n);
 80         while(q--)
 81         {
 82             scanf("%d%d%d",&op,&u,&v);
 83             if(op==2){
 84                 ll tep=query(1,1,n,u,v);
 85                 tep=v-u+1-tep;
 86                 if(tep>0)
 87                 update(1,1,n,u,u+tep-1,0);
 88                 if(tep<v-u+1)
 89                 update(1,1,n,u+tep,v,1);
 90             }else if(op==1){
 91                 if(u==1){
 92                     ll tp=query(1,1,n,u,v);
 93                     ll ans=preb[tp];
 94                     ans+=prea[v-tp];
 95                     printf("%lld\n",ans);
 96                     continue;
 97                 }
 98                 ll tp1=query(1,1,n,1,u-1);
 99                 ll tp2=query(1,1,n,1,v);
100                 ll ans=preb[tp2]-preb[tp1];
101                 tp1=u-1-tp1,tp2=v-tp2;
102                 ans+=prea[tp2]-prea[tp1];
103                 printf("%lld\n",ans);
104             }else{
105                 ll tep=query(1,1,n,u,v);
106                 if(tep>0)
107                 update(1,1,n,u,u+tep-1,1);
108                 if(tep<v-u+1)
109                 update(1,1,n,u+tep,v,0);
110             }
111         }
112     }
113 }












猜你喜欢

转载自www.cnblogs.com/zhangbuang/p/10959004.html
今日推荐