线段树练习5
来源:互联网 发布:淘宝订单多久自动关闭 编辑:程序博客网 时间:2024/06/04 01:23
题目>>http://codevs.cn/problem/4927/
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;typedef long long ll;const int MAXN = 4e5;struct zt{ ll l,r,sum,sz,jia,cnt,MAX,MIN; zt *lift,*right;};zt tree[MAXN];ll m,n,a,b,c,cnt = 0,ji;string s;void build(zt *root,ll l,ll r){ root->sum = 0;root->l = l;root->r = r;root->MAX = 0;root->MIN = 0; root->sz = r - l + 1;root->jia = 0;root->cnt = -1; if(l == r) return; root->lift = &tree[++cnt]; root->right = &tree[++cnt]; ll mid = (l + r)>>1; build(root->lift,l,mid); build(root->right,mid + 1,r);}void xf_cnt(zt *root){ root->lift->cnt = root->cnt; root->right->cnt = root->cnt; root->lift->sum = root->cnt * root->lift->sz; root->right->sum = root->cnt * root->right->sz; root->lift->MAX = root->cnt; root->right->MAX = root->cnt; root->lift->MIN = root->cnt; root->right->MIN = root->cnt; root->lift->jia = 0; root->right->jia = 0; root->cnt = -1;}void xf_jia(zt *root){ root->lift->jia += root->jia; root->right->jia += root->jia; root->lift->sum += root->jia * root->lift->sz; root->right->sum += root->jia * root->right->sz; root->lift->MAX += root->jia; root->right->MAX += root->jia; root->lift->MIN += root->jia; root->right->MIN += root->jia; root->jia = 0;}void add(zt *root,ll l,ll r,ll ql,ll qr,ll x){ if(l >= ql&&qr >= r) { root->sum += root->sz * x; root->MAX += x; root->MIN += x; root->jia += x; return; } if(root->cnt != -1) xf_cnt(root); if(root->jia) xf_jia(root); ll mid = l + r>>1; if(ql <= mid) add(root->lift,l,mid,ql,qr,x); if(qr > mid) add(root->right,mid + 1,r,ql,qr,x); root->MAX = max(root->lift->MAX,root->right->MAX); root->MIN = min(root->lift->MIN,root->right->MIN); root->sum = root->lift->sum + root->right->sum;}void set(zt *root,ll l,ll r,ll ql,ll qr,ll x){ if(l >= ql&&qr >= r) { root->sum = root->sz * x; root->cnt = x; root->jia = 0; root->MAX = x; root->MIN = x; return; } if(root->cnt != -1) xf_cnt(root); if(root->jia) xf_jia(root); ll mid = l + r>>1; if(ql <= mid) set(root->lift,l,mid,ql,qr,x); if(qr > mid) set(root->right,mid + 1,r,ql,qr,x); root->MAX = max(root->lift->MAX,root->right->MAX); root->MIN = min(root->lift->MIN,root->right->MIN); root->sum = root->lift->sum + root->right->sum;}ll find(zt *root,ll l,ll r,ll ql,ll qr){ if(l >= ql&&qr >= r) { if(s == "sum") return root->sum; if(s == "max") return root->MAX; if(s == "min") return root->MIN; } if(root->cnt != -1) xf_cnt(root); if(root->jia) xf_jia(root); ll ans = 0,mid = l + r >>1,ma = -1e15,mi = 1e15; if(s == "sum") { if(ql <= mid) ans += find(root->lift,l,mid,ql,qr); if(qr > mid) ans += find(root->right,mid + 1,r,ql,qr); } else if(s == "max") { ans = ma; if(ql <= mid) ans = find(root->lift,l,mid,ql,qr); if(qr > mid) ans = max(find(root->right,mid + 1,r,ql,qr),ans); } else if(s == "min") { ans = mi; if(ql <= mid) ans = find(root->lift,l,mid,ql,qr); if(qr > mid) ans = min(find(root->right,mid + 1,r,ql,qr),ans); } return ans;}int main(){ scanf("%lld %lld",&n,&m); build(tree,1,n); for(ll i = 1;i <= n;i ++) { scanf("%lld",&a); add(tree,1,n,i,i,a); } for(int i = 1;i <= m;i ++) { cin>>s; if(s == "add"||s == "set") { scanf("%lld %lld %lld",&a,&b,&c); if(s == "add") add(tree,1,n,a,b,c); else set(tree,1,n,a,b,c); } else { scanf("%lld %lld",&a,&b); cout<<find(tree,1,n,a,b)<<'\n'; } }}
阅读全文
0 0
- 线段树练习5
- 线段树练习5
- codevs_4927 线段树练习5
- 4927 线段树练习5
- <线段树系列4> codevs 4927 线段树练习5
- codevs4927 线段树练习5(线段树)
- Codevs 4927 线段树练习5(分块)
- Codevs 4927 线段树练习5
- 线段树练习
- Wikioi1080线段树练习
- 线段树练习
- 【wikioi1080】 线段树练习
- 线段树练习
- 线段树练习
- 线段树练习 2
- 线段树1练习
- 线段树2练习
- 线段树练习3
- Oracle Timestamp store Milliseconds
- SESSION劫持
- 使用Dom4j解析XML文件
- Canvas Frames CodeForces
- Eclipse中搭建Maven
- 线段树练习5
- python除空格和换行符
- SQL Server 开发指南
- ACM_大牛总结的线段树专辑
- HDU-2871:Memory Control(区间合并+vector二分)
- Python爬取知乎温酒小故事
- 四元数和方向
- 处理文本数据(scikit-learn 教程3)
- Object-C中的常用算法