Gorgeous Sequence
2015-11-26 15:54
411 查看
Gorgeous Sequence
时间限制: 3 Sec 内存限制: 128 MB题目描述
有一个长为n的序列,第i个数为ai。对于这个序列有三种操作方式:
0 x y t:对于任意的x≤i≤y,用min(ai,t)替换原来的ai;
1 x y:输出[x,y]区间所有元素的最大值。
2 x y:输出[x,y]区间所有元素的和。
输入
第一行一个整数T,表示测试点的个数。
对于每个测试点:
第一行两个整数n和m,分别表示序列的长度和操作的次数。
第二行包含n个整数,a1,…,an (∀1≤i≤n,0≤ai<231)。
接下来m行,每行代表一次操作,其中(1≤x≤y≤n,0≤t<231)。
所有数据保证T=100, ∑n≤1000000, ∑m≤1000000。
输出
对于每个操作1或2,请输出相应查询的答案。
样例输入
1
5 5
1 2 3 4 5
1 1 5
2 1 5
0 3 5 3
1 1 5
2 1 5
样例输出
5
15
3
12
来源
hdu2015多校
题解
对于每次修改操作,在找到一个区间后将标记尽可能下传,直到一个区间内不会增加被修改的数字时才结束。考虑复杂度,每个数字最多只会被标记一次,每次需要logn次操作。所以效率为nlogn。(瞎证明的,欢迎更科学的证明)
代码
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<algorithm> #define N 1000010 #define ll long long using namespace std; int Q,n,m,s ; struct node{int maxn,num,lazy;ll sum;}t[N*4]; inline int get() { char ch; while(!isdigit(ch=getchar())); int v=ch-48; while(isdigit(ch=getchar()))v=v*10+ch-48; return v; } class seg_tree { inline void update(int x) { int lc=x<<1,rc=lc+1; t[x].maxn=max(t[lc].maxn,t[rc].maxn); t[x].sum=t[lc].sum+t[rc].sum; t[x].num=t[lc].num+t[rc].num; } void work(int x,int l,int r,int num) { if(t[x].lazy<=num&&t[x].lazy)return; t[x].lazy=num;t[x].sum+=(ll)(r-l+1-t[x].num)*num; if(t[x].num<r-l+1)t[x].maxn=num,t[x].num=r-l+1; } inline void pushdown(int x,int l,int r) { if(!t[x].lazy)return; int mid=l+r>>1,lc=x<<1,rc=lc+1; work(lc,l,mid,t[x].lazy); work(rc,mid+1,r,t[x].lazy); t[x].lazy=0; } public: inline void build(int x,int l,int r) { t[x].lazy=0; if(l==r) { t[x].maxn=s[l];t[x].lazy=s[l]; t[x].sum=s[l];t[x].num=1;return; } int mid=l+r>>1,lc=x<<1,rc=lc+1; build(lc,l,mid);build(rc,mid+1,r); update(x); } inline void find(int x,int l,int r,int num) { if(t[x].maxn<=num)return; if(t[x].lazy>num)t[x].lazy=0; if(l==r) { t[x].maxn=t[x].lazy;t[x].sum=t[x].lazy; t[x].num=t[x].lazy?1:0;return; } int mid=l+r>>1,lc=x<<1,rc=lc+1; pushdown(x,l,r); find(lc,l,mid,num); find(rc,mid+1,r,num); update(x); } inline void modify(int x,int l,int r,int ql,int qr,int num) { if(t[x].maxn<=num)return; if(ql<=l&&r<=qr){find(x,l,r,num);work(x,l,r,num);return;} int mid=l+r>>1,lc=x<<1,rc=lc+1; pushdown(x,l,r); if(ql<=mid)modify(lc,l,mid,ql,qr,num); if(qr>mid)modify(rc,mid+1,r,ql,qr,num); update(x); } inline int qry1(int x,int l,int r,int ql,int qr) { if(ql<=l&&r<=qr)return t[x].maxn; int mid=l+r>>1,lc=x<<1,rc=lc+1,res=0; pushdown(x,l,r); if(ql<=mid)res=max(res,qry1(lc,l,mid,ql,qr)); if(qr>mid)res=max(res,qry1(rc,mid+1,r,ql,qr)); return res; } inline ll qry2(int x,int l,int r,int ql,int qr) { if(ql<=l&&r<=qr)return t[x].sum; int mid=l+r>>1,lc=x<<1,rc=lc+1;ll res=0; pushdown(x,l,r); if(ql<=mid)res+=qry2(lc,l,mid,ql,qr); if(qr>mid)res+=qry2(rc,mid+1,r,ql,qr); return res; } }T; int main() { int type,a,b,c; Q=get(); while(Q--) { n=get();m=get(); for(int i=1;i<=n;i++)s[i]=get(); T.build(1,1,n); for(int i=1;i<=m;i++) { type=get();a=get();b=get(); if(!type)c=get(),T.modify(1,1,n,a,b,c); if(type==1)printf("%d\n",T.qry1(1,1,n,a,b)); if(type==2)printf("%lld\n",T.qry2(1,1,n,a,b)); } } return 0; }
相关文章推荐
- UICollectionView的使用
- UIView常见属性(一)
- 使用CruiseControl.Net全面实现持续集成
- UI_搜索框UISearchController的使用(iOS8.0以后替代UISearchBar + UISearchDisplayController)
- Xcode调试UI
- EasyUI常见几种控件动态渲染的示范代码
- easyui-tooltip 提示框
- UI_UISearchController实现搜索功能
- iOS Human Interface Guidelines资源收藏
- PHP在foreach中对$value赋值无效的问题
- Extjs4.2 combobox setValue设置值
- PredicateBuilder 对 ADO.Net Entity Framework 支持的改进
- Machine Learning week 7 quiz: Support Vector Machines
- iso中输入框被软键盘覆盖的解决方案
- android UI学习书籍
- UserInterface的使用总结篇(完结篇)
- easyui-resizable 调整大小
- 1.5 Technologies for Building Processors and Memory
- hive使用orcfile parquet sequencefile
- UI_界面传值方式