CODEVS 1081 线段树练习 2 题解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CODEVS 1081 线段树练习 2 题解相关的知识,希望对你有一定的参考价值。
此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。
题目链接:http://codevs.cn/problem/1081/
题目描述 Description
给你N个数,有两种操作
1:给区间[a,b]的所有数都增加X
2:询问第i个数是什么?
输入描述
Input Description
第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,表示操作的个数. 接下来Q行每行若干个整数。如果第一个数是1,后接3个正整数a,b,X,表示在区间[a,b]内每个数增加X,如果是2,后面跟1个整数i, 表示询问第i个位置的数是多少。
输出描述
Output Description
对于每个询问输出一行一个答案
样例输入
Sample Input
3
1
2
3
2
1 2 3 2
2 3
样例输出
Sample Output
5
数据范围及提示
Data Size & Hint
数据范围
1<=n<=100000
1<=q<=100000
分析:
区间修改的线段树,使用lazy标记。反正是个板子qwq
AC代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 6 const int MAXN = 100005; 7 8 inline void read(int &x) 9 { 10 char ch = getchar(),c = ch;x = 0; 11 while(ch < ‘0‘ || ch > ‘9‘) c = ch,ch = getchar(); 12 while(ch <= ‘9‘ && ch >= ‘0‘) x = (x<<1)+(x<<3)+ch-‘0‘,ch = getchar(); 13 if(c == ‘-‘) x = -x; 14 } 15 16 int num[MAXN],sdata[MAXN<<2],slazy[MAXN<<2]; 17 18 inline void update(int o) 19 { 20 sdata[o] = sdata[o<<1] + sdata[o<<1|1]; 21 } 22 23 void build(int l,int r,int o) 24 { 25 if(l == r) 26 { 27 sdata[o] = num[l]; 28 return; 29 } 30 int mid = (l+r)>>1; 31 build(l,mid,o<<1); 32 build(mid+1,r,o<<1|1); 33 update(o); 34 } 35 36 void putdown(int l,int r,int o) 37 { 38 slazy[o<<1] += slazy[o]; 39 slazy[o<<1|1] += slazy[o]; 40 int mid = (l+r) >> 1; 41 sdata[o<<1] += (mid-l+1)*slazy[o]; 42 sdata[o<<1|1] += (r-mid)*slazy[o]; 43 slazy[o] = 0; 44 } 45 46 void change(int l,int r,int o,int ll,int rr,int k) 47 { 48 if(ll <= l && rr >= r) 49 { 50 sdata[o] += (r-l+1)*k; 51 slazy[o] += k; 52 return; 53 } 54 if(slazy[o]) putdown(l,r,o); 55 int mid = (l+r)>>1; 56 if(mid >= ll) change(l,mid,o<<1,ll,rr,k); 57 if(mid < rr) change(mid+1,r,o<<1|1,ll,rr,k); 58 update(o); 59 } 60 61 int ask(int l,int r,int o,int p) 62 { 63 if(l == r && r == p) 64 { 65 return sdata[o]; 66 } 67 if(slazy[o]) putdown(l,r,o); 68 int mid = (l+r)>>1; 69 int ans = 0; 70 if(p <= mid) ans = ask(l,mid,o<<1,p); 71 else ans = ask(mid+1,r,o<<1|1,p); 72 return ans; 73 } 74 75 int main() 76 { 77 int n,m,op,a,b,c; 78 read(n); 79 for(int i = 1;i <= n;++ i) 80 read(num[i]); 81 build(1,n,1); 82 read(m); 83 for(int i = 1;i <= m;++ i) 84 { 85 read(op); 86 if(op == 1) 87 { 88 read(a),read(b),read(c); 89 change(1,n,1,a,b,c); 90 } 91 else 92 { 93 read(a); 94 printf("%d\n",ask(1,n,1,a)); 95 } 96 } 97 return 0; 98 }
以上是关于CODEVS 1081 线段树练习 2 题解的主要内容,如果未能解决你的问题,请参考以下文章