bzoj 4695 最假女选手 吉利线段树
最假女选手
Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 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
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 }