BZOJ 4695
来源:互联网 发布:2k17德拉蒙德格林数据 编辑:程序博客网 时间:2024/06/10 17:39
4695: 最假女选手
Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 126 Solved: 23
[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
1操作好搞
2操作就维护一个次大值,一个最大值和最大值出现次数(复杂度证明在传送门)
在x>=最大值时return
在x<次大值时继续递归modify
在次大值<=x<最大值时打上标记
更新时很恶心,先要更新sum,然后要用x去更新最大值,最小值和次小值
如果最小值==最大值,说明这个区间内数已经相同了,就需要再次修改次大次小值
要把3操作的标记更新.
其他操作就随意脑补一下好了
PS:我好像写丑了...加了读入优化,BZOJ续了1s才过...
#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#define inf (1<<30)#define maxn 500005using namespace std;typedef long long ll;struct segtree{ ll add,sum; int mntox,mxtox,mxs,mns,mx1,mx2,mn1,mn2,l,r; void clear(){mx1=mx2=-inf;mn1=mn2=inf;sum=add=mxs=mns=0;mntox=-inf,mxtox=inf;}}s[maxn<<2];int a[maxn],n,m;int inline read(){ register char act=0; register int f=1,x=0; while(act=getchar(),act<'0'&&act!='-'); if(act=='-')f=-1,act=getchar(); x=act-'0'; while(act=getchar(),act>='0')x=x*10+act-'0'; return x*f;} bool updmax(int o,int mxtox){ if(s[o].mx1<=mxtox)return 0; if(s[o].mx2<mxtox){// printf("max{%d,%d,(%d,%d)}",s[o].mxs,s[o].mx1,s[o].l,s[o].r); s[o].sum=s[o].sum-(ll)s[o].mxs*s[o].mx1+(ll)s[o].mxs*mxtox; s[o].mn1=min(s[o].mn1,s[o].mx1=mxtox); s[o].mn2=min(s[o].mn2,mxtox); if(s[o].mn1==mxtox)s[o].mn2=inf,s[o].mx2=-inf,s[o].mxs=s[o].mns=s[o].r-s[o].l+1; s[o].mntox=min(s[o].mxtox=min(s[o].mxtox,mxtox),s[o].mntox); return 0; } return 1;}bool updmin(int o,int mntox){ if(s[o].mn1>=mntox)return 0; if(s[o].mn2>mntox){// printf("min{%d,%d,(%d,%d)}",s[o].mns,s[o].mn1,s[o].l,s[o].r); s[o].sum=s[o].sum-(ll)s[o].mns*s[o].mn1+(ll)s[o].mns*mntox; s[o].mx1=max(s[o].mx1,s[o].mn1=mntox); s[o].mx2=max(s[o].mx2,mntox); if(s[o].mx1==mntox)s[o].mx2=-inf,s[o].mn2=inf,s[o].mxs=s[o].mns=s[o].r-s[o].l+1; s[o].mxtox=max(s[o].mntox=max(s[o].mntox,mntox),s[o].mxtox); return 0; } return 1;}void xadd(int& x,int y){ if(x==inf||x==-inf)return ; x+=y;}void pushdown(int o){ if(s[o].add){ s[o<<1].add+=s[o].add; s[o<<1].sum+=(ll)s[o].add*(s[o<<1].r-s[o<<1].l+1); s[o<<1].mx1+=s[o].add,s[o<<1].mn1+=s[o].add; xadd(s[o<<1].mxtox,s[o].add),xadd(s[o<<1].mntox,s[o].add); xadd(s[o<<1].mx2,s[o].add),xadd(s[o<<1].mn2,s[o].add); s[o<<1|1].add+=s[o].add; s[o<<1|1].sum+=(ll)s[o].add*(s[o<<1|1].r-s[o<<1|1].l+1); s[o<<1|1].mx1+=s[o].add,s[o<<1|1].mn1+=s[o].add; xadd(s[o<<1|1].mxtox,s[o].add),xadd(s[o<<1|1].mntox,s[o].add); xadd(s[o<<1|1].mx2,s[o].add),xadd(s[o<<1|1].mn2,s[o].add); s[o].add=0; } if(s[o].mxtox!=inf){ updmax(o<<1,s[o].mxtox); updmax(o<<1|1,s[o].mxtox); s[o].mxtox=inf; } if(s[o].mntox!=-inf){ updmin(o<<1,s[o].mntox); updmin(o<<1|1,s[o].mntox); s[o].mntox=-inf; }}void pushup(ll o){ int ls=o<<1,rs=o<<1|1; s[o].sum=s[ls].sum+s[rs].sum+(ll)s[o].add*(s[o].r-s[o].l+1); s[o].mx1=max(s[ls].mx1,s[rs].mx1); s[o].mx2=max(s[ls].mx2,s[rs].mx2); s[o].mxs=s[o].mns=0; if(s[o].mx1==s[ls].mx1)s[o].mxs+=s[ls].mxs; else if(s[o].mx2<s[ls].mx1)s[o].mx2=s[ls].mx1; if(s[o].mx1==s[rs].mx1)s[o].mxs+=s[rs].mxs; else if(s[o].mx2<s[rs].mx1)s[o].mx2=s[rs].mx1; s[o].mx1+=s[o].add; s[o].mn1=min(s[ls].mn1,s[rs].mn1); s[o].mn2=min(s[ls].mn2,s[rs].mn2); if(s[o].mn1==s[ls].mn1)s[o].mns+=s[ls].mns; else if(s[o].mn2>s[ls].mn1)s[o].mn2=s[ls].mn1; if(s[o].mn1==s[rs].mn1)s[o].mns+=s[rs].mns; else if(s[o].mn2>s[rs].mn1)s[o].mn2=s[rs].mn1; s[o].mn1+=s[o].add; xadd(s[o].mn2,s[o].add); xadd(s[o].mx2,s[o].add);}void build(int o,int l,int r){ s[o].l=l,s[o].r=r; s[o].clear(); if(l==r){ s[o].mx1=s[o].mn1=a[l]; s[o].mxs=1,s[o].mns=1; s[o].sum=a[l]; return ; } int mid=l+r>>1; build(o<<1,l,mid); build(o<<1|1,mid+1,r); pushup(o);}void modify1(int o,int ql,int qr,int a){ if(ql<=s[o].l&&s[o].r<=qr){ s[o].sum+=(ll)(s[o].r-s[o].l+1)*a; s[o].mx1+=a,s[o].mxtox+=a; s[o].mn1+=a,s[o].mntox+=a; xadd(s[o].mx2,a); xadd(s[o].mn2,a); s[o].add+=a; return ; } pushdown(o); if(ql<=s[o<<1].r)modify1(o<<1,ql,qr,a); if(s[o<<1|1].l<=qr)modify1(o<<1|1,ql,qr,a); pushup(o);}void modify2(ll o,ll ql,ll qr,ll a){ if(ql<=s[o].l&&s[o].r<=qr&&!updmin(o,a)) return ; pushdown(o); if(ql<=s[o<<1].r)modify2(o<<1,ql,qr,a); if(s[o<<1|1].l<=qr)modify2(o<<1|1,ql,qr,a); pushup(o);}void modify3(ll o,ll ql,ll qr,ll a){// printf("[%d,%d,%d]",s[o].l,s[o].r,s[o].mx1); if(ql<=s[o].l&&s[o].r<=qr&&!updmax(o,a)) return ; pushdown(o); if(ql<=s[o<<1].r)modify3(o<<1,ql,qr,a); if(s[o<<1|1].l<=qr)modify3(o<<1|1,ql,qr,a); pushup(o);}ll querysum(int o,int ql,int qr){ if(ql<=s[o].l&&s[o].r<=qr)return s[o].sum; pushdown(o); ll ans=0; if(ql<=s[o<<1].r)ans+=querysum(o<<1,ql,qr); if(s[o<<1|1].l<=qr)ans+=querysum(o<<1|1,ql,qr); return ans;}int querymx(int o,int ql,int qr){ if(ql<=s[o].l&&s[o].r<=qr)return s[o].mx1; pushdown(o); int ans=-inf; if(ql<=s[o<<1].r)ans=max(ans,querymx(o<<1,ql,qr)); if(s[o<<1|1].l<=qr)ans=max(ans,querymx(o<<1|1,ql,qr)); return ans;}int querymn(int o,int ql,int qr){ if(ql<=s[o].l&&s[o].r<=qr)return s[o].mn1; pushdown(o); int ans=inf; if(ql<=s[o<<1].r)ans=min(ans,querymn(o<<1,ql,qr)); if(s[o<<1|1].l<=qr)ans=min(ans,querymn(o<<1|1,ql,qr)); return ans;}int main(){ n=read(); for(int i=1;i<=n;++i)a[i]=read(); build(1,1,n); m=read(); for(int i=1;i<=m;++i){ int tp,l,r,x;tp=read(); if(tp<=3)l=read(),r=read(),x=read(); else l=read(),r=read(); if(tp==1)modify1(1,l,r,x); else if(tp==2)modify2(1,l,r,x); else if(tp==3)modify3(1,l,r,x); else if(tp==4)printf("%lld\n",querysum(1,l,r)); else if(tp==5)printf("%d\n",querymx(1,l,r)); else if(tp==6)printf("%d\n",querymn(1,l,r));// printf("[%d:%d]\n",s[1].mn1,s[1].sum);// printf("[ok]"); }}
0 0
- BZOJ 4695
- [BZOJ ]
- BZOJ****-****
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- bzoj
- bzoj
- BZOJ
- BZOJ
- bzoj
- Android源码设计模式分析项目
- gcc编译的时候一个undefined reference to `xxx'的一个细节
- MyBatis(2):config.xml文件
- Eclipse使用git最基本流程
- 12.24
- BZOJ 4695
- tbschedule源码学习
- 光纤通信原理
- gcc 软连接
- Java并发之线程池(三)
- 2016年12月
- 法律网推荐(二) 用Pig进行数据预处理
- C语言实验——大小写转换
- POJ 2068 Nim 已翻译