whu Problem 1464 - Deal with numbers
2014-05-12 15:35
239 查看
http://acm.whu.edu.cn/land/problem/detail?problem_id=1464
带延迟标记的线段树,只不过这道题目比一般的线段树稍微复杂一点。
标记的操作总共有两种,减操作和除操作。对于每一种除操作要进行到叶子节点,但是对于减操作,可以只进行到目标区间,在查询的时候沿着查询区间往下更新。
带延迟标记的线段树,只不过这道题目比一般的线段树稍微复杂一点。
标记的操作总共有两种,减操作和除操作。对于每一种除操作要进行到叶子节点,但是对于减操作,可以只进行到目标区间,在查询的时候沿着查询区间往下更新。
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<string.h> #include<stdlib.h> #include<algorithm> using namespace std; typedef long long LL; const int inf = 100010; const int MAX = 0x7fffffff; LL sum[4*inf],maxx[4*inf],add[4*inf]; bool b[4*inf]; int n,m; void pushup(int root) { sum[root] = sum[2*root] + sum[2*root+1]; b[root] = b[2*root] | b[2*root+1]; } void pushdown(int num,int root) { add[2*root] += add[root]; add[2*root+1] += add[root]; sum[2*root] -= (num - num/2) * add[root]; sum[2*root+1] -= (num/2) * add[root]; add[root] = 0; } void build(int l,int r,int root) { add[root] = 0; if(l == r) { scanf("%lld",&sum[root]); b[root] = sum[root]>0; return ; } int mid = (l+r)/2; build(l,mid,2*root); build(mid+1,r,2*root+1); pushup(root); } void update1(int L,int R,int div,int l, int r,int root) { if(!b[root]) return ; if(l == r) { if(sum[root] > 0) sum[root] /= div; b[root] = sum[root]>0; return ; } if(add[root]) pushdown(r-l+1,root); int mid = (l + r)/2; if(L <= mid) update1(L,R,div,l,mid,2*root); if(R > mid) update1(L,R,div,mid+1,r,2*root+1); pushup(root); } void update2(int L,int R,int v,int l ,int r,int root) { if(L <= l && R >= r) { sum[root] -= (r - l +1)*v; add[root] += v; return ; } if(add[root]) pushdown(r-l+1,root); int mid = (l+r)/2; if(L <= mid) update2(L,R,v,l,mid,2*root); if(R > mid) update2(L,R,v,mid+1,r,2*root+1); pushup(root); } LL query(int L,int R,int l ,int r, int root) { if(L <= l && R >= r) { return sum[root]; //printf("%lld\n",sum[root]); } if(add[root]) pushdown(r-l+1,root); int mid = (l+r)/2; LL res = 0 ; if(L <= mid) res += query(L,R,l,mid,2*root); if(R > mid) res += query(L,R,mid+1,r,2*root+1); return res; } int main() { //freopen("1.txt","w",stdout); int t,a,b,c,i,num = 0; char s[15]; cin>>t; while(t--) { printf("Case %d:\n",++num); scanf("%d%d",&n,&m); build(1,n,1); for(i = 1; i <= m; i++) { scanf(" %s%d%d",s,&a,&b); if(s[0] == 'D') { scanf("%d",&c); if(c == 1) continue; update1(a,b,c,1,n,1); } if(s[0] == 'M') { scanf("%d",&c); if(c == 0) continue; update2(a,b,c,1,n,1); } if(s[0] == 'S') { printf("%lld\n",query(a,b,1,n,1)); } } puts(""); } return 0; }
相关文章推荐
- Bnuoj-29359 Deal with numbers 线段树
- whu 1464 Deal whth Numbers 线段树维护区间除法
- TOJ 4399 Deal with numbers / 线段树成段更新
- LeetCode: Count Numbers with Unique Digits
- how to deal with error SPARK-5063 in spark
- 00-自测4. Have Fun with Numbers (20)
- 每天一道编程题——Have Fun with Numbers
- How Python GC deal with reference-cycles?
- 1023. Have Fun with Numbers (20)
- 1023. Have Fun with Numbers (20)
- How to deal with an SVM with categorical attributes?
- pat 1023. Have Fun with Numbers (大水)
- 自测-4 Have Fun with Numbers
- PAT (Advanced Level) Practise 1023 Have Fun with Numbers (20)
- Tip/Trick: ASP.NET 2.0 Deal with DBNull value when bind to RadioButtonList/当绑定RadioButtonL
- U.S. to Seek Textile Deal With China
- PAT Have fun with numbers (Python)
- PTA自测-4 Have Fun with Numbers
- PAT A1023. Have Fun with Numbers (20)
- PAT 1023. Have Fun with Numbers (20)(字符串转换,20位数的加法)