bzoj 4695 最假女选手 吉利线段树

 最假女选手

Time Limit: 50 Sec  Memory Limit: 128 MB
Submit: 480  Solved: 118
[Submit][Status][Discuss]

Description

在刚刚结束的水题嘉年华的压轴节目放水大赛中,wyywyy如愿以偿的得到了最假女选手的奖项。但是作为主办人的
C_SUNSHINE为了证明wyywyy确实在放水,决定出一道基础题考察wyywyy的姿势水平。给定一个长度为 N序列,编号
从1 到 N。要求支持下面几种操作:
1.给一个区间[L,R] 加上一个数x 
2.把一个区间[L,R] 里小于x 的数变成x 
3.把一个区间[L,R] 里大于x 的数变成x 
4.求区间[L,R] 的和
5.求区间[L,R] 的最大值
6.求区间[L,R] 的最小值

 

Input

第一行一个整数 N表示序列长度。
第二行N 个整数Ai 表示初始序列。
第三行一个整数M 表示操作个数。
接下来M 行,每行三或四个整数,第一个整数Tp 表示操作类型,接下来L,R,X 或L,R 表述操作数。
1<=tp<=6,N,M<=5*10^5,|Ai|<=10^8
Tp=1时,|x|<=1000
Tp=2或3时,|x|<=10^8

 

Output

对于每个4,5,6类型的操作输出一行一个整数表示答案。

 

Sample Input

2
1 2
2
2 1 2 2
4 1 2

Sample Output

4

HINT

 

题解:吉利线段树的模板题

https://pan.baidu.com/s/1o7xSSQ2

  1 #include<cstring>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<iostream>
  5 #include<cmath>
  6 #include<queue>
  7 #include<map>
  8 
  9 #define ll long long
 10 #define inf 1000000007
 11 #define N 500007
 12 #define ls p<<1
 13 #define rs p<<1|1
 14 using namespace std;
 15 inline ll read()
 16 {
 17     ll x=0,f=1;char ch=getchar();
 18     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
 19     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
 20     return x*f;
 21 }
 22 
 23 int n,m;
 24 int mx[N<<2],cx[N<<2],sx[N<<2];//区间最大值,最大值个数 ,区间严格次大值
 25 int mn[N<<2],cn[N<<2],sn[N<<2];//区间最小值,最小值个数 ,区间严格次小值
 26 int add[N<<2];//区间tag标记 
 27 ll sum[N<<2];//区间和 
 28 
 29 inline void push_up(int p)
 30 {
 31     sum[p]=sum[ls]+sum[rs];
 32     
 33     if (mx[ls]>mx[rs]) mx[p]=mx[ls],cx[p]=cx[ls],sx[p]=max(sx[ls],mx[rs]);    
 34     if (mx[ls]<mx[rs]) mx[p]=mx[rs],cx[p]=cx[rs],sx[p]=max(mx[ls],sx[rs]);
 35     if (mx[ls]==mx[rs]) mx[p]=mx[ls],cx[p]=cx[ls]+cx[rs],sx[p]=max(sx[ls],sx[rs]);
 36     
 37     if (mn[ls]<mn[rs]) mn[p]=mn[ls],cn[p]=cn[ls],sn[p]=min(sn[ls],mn[rs]);
 38     if (mn[ls]>mn[rs]) mn[p]=mn[rs],cn[p]=cn[rs],sn[p]=min(mn[ls],sn[rs]);
 39     if (mn[ls]==mn[rs]) mn[p]=mn[ls],cn[p]=cn[ls]+cn[rs],sn[p]=min(sn[ls],sn[rs]);
 40    // cout<<sum[p]<<endl;
 41 }
 42 inline void push_down(int p,int l,int r)
 43 {
 44     if (add[p])
 45     {
 46         int mid=(l+r)>>1;
 47         mx[ls]+=add[p],sx[ls]+=add[p],mn[ls]+=add[p],sn[ls]+=add[p],sum[ls]+=(mid-l+1)*add[p],add[ls]+=add[p];
 48         mx[rs]+=add[p],sx[rs]+=add[p],mn[rs]+=add[p],sn[rs]+=add[p],sum[rs]+=(r-mid)*add[p],add[rs]+=add[p];
 49         add[p]=0; 
 50     }
 51     if (mx[ls]>mx[p])
 52     {
 53         if (mn[ls]==mx[ls]) mn[ls]=mx[p];
 54         if (sn[ls]==mx[ls]) sn[ls]=mx[p];
 55         sum[ls]+=1ll*(mx[p]-mx[ls])*cx[ls],mx[ls]=mx[p];
 56     }
 57     if (mx[rs]>mx[p])
 58     {
 59         if (mn[rs]==mx[rs]) mn[rs]=mx[p];
 60         if (sn[rs]==mx[rs]) sn[rs]=mx[p];
 61         sum[rs]+=1ll*(mx[p]-mx[rs])*cx[rs],mx[rs]=mx[p];
 62     }
 63     if (mn[ls]<mn[p])
 64     {
 65         if (mx[ls]==mn[ls]) mx[ls]=mn[p];
 66         if (sx[ls]==mn[ls]) sx[ls]=mn[p];
 67         sum[ls]+=1ll*(mn[p]-mn[ls])*cn[ls],mn[ls]=mn[p];
 68     }
 69     if (mn[rs]<mn[p])
 70     {
 71         if (mx[rs]==mn[rs]) mx[rs]=mn[p];
 72         if (sx[rs]==mn[rs]) sx[rs]=mn[p];
 73         sum[rs]+=1ll*(mn[p]-mn[rs])*cn[rs],mn[rs]=mn[p];
 74     }
 75 }
 76 void build(int p,int l,int r)
 77 {
 78     if (l==r)
 79     {
 80         mx[p]=mn[p]=sum[p]=read();
 81         cx[p]=cn[p]=1;
 82         sx[p]=-inf,sn[p]=inf;
 83         return;
 84     }
 85     int mid=(l+r)>>1;
 86     build(ls,l,mid),build(rs,mid+1,r);
 87     push_up(p);
 88 }
 89 void vadd(int p,int l,int r,int x,int y,int z)
 90 {
 91     if (l==x&&y==r)
 92     {
 93         mx[p]+=z,sx[p]+=z,mn[p]+=z,sn[p]+=z;
 94         sum[p]+=1ll*(r-l+1)*z,add[p]+=z;
 95         return;
 96     }
 97     push_down(p,l,r);
 98     int mid=(l+r)>>1;
 99     if (y<=mid) vadd(ls,l,mid,x,y,z);
100     else if (x>mid) vadd(rs,mid+1,r,x,y,z);
101     else vadd(ls,l,mid,x,mid,z),vadd(rs,mid+1,r,mid+1,y,z);
102     push_up(p);
103 }
104 void vmax(int p,int l,int r,int x,int y,int z)
105 {
106     //cout<<p<<" "<<l<<" "<<r<<" "<<x<<" "<<y<<" "<<z<<endl;
107     if (mn[p]>=z) return;
108     if (l==x&&y==r&&sn[p]>z)
109     {
110         //cout<<p<<" "<<l<<" "<<r<<endl;
111         if (mx[p]==mn[p]) mx[p]=z;
112         if (sx[p]==mn[p]) sx[p]=z;
113         sum[p]+=1ll*(z-mn[p])*cn[p],mn[p]=z;
114         return;
115     }
116     push_down(p,l,r);
117     int mid=(l+r)>>1;
118     if (y<=mid) vmax(ls,l,mid,x,y,z);
119     else if (x>mid) vmax(rs,mid+1,r,x,y,z);
120     else vmax(ls,l,mid,x,mid,z),vmax(rs,mid+1,r,mid+1,y,z);
121     push_up(p);
122 }
123 void vmin(int p,int l,int r,int x,int y,int z)
124 {
125     if (mx[p]<=z) return;
126     if (l==x&&y==r&&sx[p]<z)
127     {
128         //cout<<l<<" "<<r<<" "<<p<<endl;
129         if (mn[p]==mx[p]) mn[p]=z;
130         if (sn[p]==mx[p]) sn[p]=z;
131         sum[p]+=1ll*(z-mx[p])*cx[p],mx[p]=z;
132     //    cout<<sum[p]<<" "<<l<<" "<<r<<" "<<p<<endl;
133         return;
134     }
135     push_down(p,l,r);
136     int mid=(l+r)>>1;
137     if (y<=mid) vmin(ls,l,mid,x,y,z);
138     else if (x>mid) vmin(rs,mid+1,r,x,y,z);
139     else vmin(ls,l,mid,x,mid,z),vmin(rs,mid+1,r,mid+1,y,z);
140 //    cout<<l<<" "<<r<<" "<<sum[p]<<endl;
141     push_up(p);
142 //    cout<<p<<" "<<l<<" "<<r<<" "<<sum[p]<<" "<<sum[ls]<<" "<<sum[rs]<<endl;
143 }
144 ll qsum(int p,int l,int r,int x,int y)
145 {
146     //cout<<l<<" "<<r<<" "<<p<<" "<<sum[p]<<endl;
147     if (l==x&&y==r) return sum[p];
148     push_down(p,l,r);
149     int mid=(l+r)>>1;
150     if (y<=mid) return qsum(ls,l,mid,x,y);
151     else if (x>mid) return qsum(rs,mid+1,r,x,y);
152     else return qsum(ls,l,mid,x,mid)+qsum(rs,mid+1,r,mid+1,y);
153 }
154 int qmax(int p,int l,int r,int x,int y)
155 {
156     if (l==x&&y==r) return mx[p];
157     push_down(p,l,r);
158     int mid=(l+r)>>1;
159     if (y<=mid) return qmax(ls,l,mid,x,y);
160     else if (x>mid) return qmax(rs,mid+1,r,x,y);
161     else return max(qmax(ls,l,mid,x,mid),qmax(rs,mid+1,r,mid+1,y));
162 }
163 int qmin(int p,int l,int r,int x,int y)
164 {
165     if (l==x&&y==r) return mn[p];
166     push_down(p,l,r);
167     int mid=(l+r)>>1;
168     if (y<=mid) return qmin(ls,l,mid,x,y);
169     else if (x>mid) return qmin(rs,mid+1,r,x,y);
170     else return min(qmin(ls,l,mid,x,mid),qmin(rs,mid+1,r,mid+1,y));
171 }
172 int main()
173 {
174     freopen("fzy.in","r",stdin);
175     freopen("fzy.out","w",stdout);
176     
177     n=read();
178     build(1,1,n);
179     m=read();
180     while(m--)
181     {
182         int opt=read(),x=read(),y=read(),z;
183         if (opt==1) z=read(),vadd(1,1,n,x,y,z);
184         if (opt==2) z=read(),vmax(1,1,n,x,y,z);
185         if (opt==3) z=read(),vmin(1,1,n,x,y,z);
186         if (opt==4) printf("%lld\n",qsum(1,1,n,x,y));
187         if (opt==5) printf("%d\n",qmax(1,1,n,x,y));
188         if (opt==6) printf("%d\n",qmin(1,1,n,x,y));
189     }
190 }

 

posted @ 2018-04-15 16:22  Kaiser-  阅读(435)  评论(0编辑  收藏  举报