博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线段树专辑—— pku 3468 A Simple Problem with Integers
阅读量:5134 次
发布时间:2019-06-13

本文共 2671 字,大约阅读时间需要 8 分钟。

典型的一道基于lazy传递的线段树题目,这题和一般题目不同的地方在于,它的每次操作不是简单的覆盖线段,而是累加。记得第一次写的时候纠结了好久。

好的,既然是累加,那么如何传递lazy呢?答案是传递累加值!

为线段树加一个add域,表示该线段需要加几。如果某区间的add不为0,那么就将该区间的add传递给其子区间,并且跟新子区间的sum_val值。

解这题最关键的就是要能够分清楚啥东西要传递,传递下去将有什么影响,其他的都好说!整体来说还是蛮轻松的

View Code
1 #include
2 #include
3 #include
4 using namespace std; 5 6 struct node 7 {
8 int l; 9 int r; 10 __int64 add; 11 __int64 sum_val; 12 }; 13 14 node tree[500000]; 15 int n,m; 16 __int64 num[100001]; 17 18 void build(int i,int l,int r) 19 {
20 tree[i].l=l; 21 tree[i].r=r; 22 tree[i].add=0; 23 if(l==r) 24 {
25 tree[i].sum_val=num[l]; 26 return; 27 } 28 int mid=(l+r)/2; 29 build(2*i,l,mid); 30 build(2*i+1,mid+1,r); 31 tree[i].sum_val=tree[2*i].sum_val+tree[2*i+1].sum_val; 32 } 33 34 void updata(int i,int l,int r,__int64 w) 35 {
36 if(tree[i].l>r || tree[i].r
=l && tree[i].r<=r) 39 {
40 tree[i].add+=w; //注意是+=,因为这不是简单的覆盖 41 tree[i].sum_val+=(tree[i].r-tree[i].l+1)*w; //由于区间所有的值都需要加上w,那么自然整段区间就是加上(w*区间大小)了 42 return; 43 } 44 if(tree[i].add!=0) 45 {
46 tree[2*i].add+=tree[i].add; //同上,注意是+= 47 tree[2*i+1].add+=tree[i].add; 48 tree[2*i].sum_val+=(tree[2*i].r-tree[2*i].l+1)*tree[i].add; 49 tree[2*i+1].sum_val+=(tree[2*i+1].r-tree[2*i+1].l+1)*tree[i].add; 50 tree[i].add=0; 51 } 52 updata(2*i,l,r,w); 53 updata(2*i+1,l,r,w); 54 tree[i].sum_val=tree[2*i].sum_val+tree[2*i+1].sum_val; //回溯跟新 55 } 56 57 __int64 ans; 58 void find(int i,int l,int r) 59 {
60 if(tree[i].l>r || tree[i].r
=l && tree[i].r<=r) 63 {
64 ans+=tree[i].sum_val; 65 return; 66 } 67 if(tree[i].add!=0) 68 {
69 tree[2*i].add+=tree[i].add; 70 tree[2*i+1].add+=tree[i].add; 71 tree[2*i].sum_val+=(tree[2*i].r-tree[2*i].l+1)*tree[i].add; 72 tree[2*i+1].sum_val+=(tree[2*i+1].r-tree[2*i+1].l+1)*tree[i].add; 73 tree[i].add=0; 74 } 75 find(2*i,l,r); 76 find(2*i+1,l,r); 77 } 78 79 int main() 80 {
81 int i,a,b; 82 __int64 w; 83 char c; 84 freopen("in.txt","r",stdin); 85 while(scanf("%d%d",&n,&m)==2) 86 {
87 for(i=1;i<=n;i++) 88 {
89 scanf("%I64d",&num[i]); 90 } 91 build(1,1,n); 92 for(i=0;i

 

转载于:https://www.cnblogs.com/ka200812/archive/2011/11/09/2243657.html

你可能感兴趣的文章
python基础学习第二天
查看>>
java可重入锁reentrantlock
查看>>
浅谈卷积神经网络及matlab实现
查看>>
struts2学习(9)struts标签2(界面标签、其他标签)
查看>>
Android 导入jar包 so模块--导入放置的目录
查看>>
解决ajax请求cors跨域问题
查看>>
Android Studio
查看>>
zz 圣诞丨太阁所有的免费算法视频资料整理
查看>>
【大数模板】C++大数类 大数模板
查看>>
【123】
查看>>
《收获,不止Oracle》pdf
查看>>
用户权限设置
查看>>
java 之equals与"=="的区别
查看>>
LinkedList<E>源码分析
查看>>
学习微软 Excel 2002 VBA 编程和XML,ASP技术
查看>>
游戏开发常用算法
查看>>
Real-Time Rendering 笔记
查看>>
如何理解HTML结构的语义化
查看>>
Intellij IDEA(eclipse设置)常用快捷键
查看>>
深入理解Java:注解(Annotation)基本概念
查看>>