线段树原来遇到过了,不过自己写还是很容易出现问题,特别是递归的时候总是忘记返回,这样老是会爆栈
还有,好像分析问题的能力很欠缺,而且宏观的概念不是很好,其实感觉写递归就两点,第一宏观上整体把握,第二细节上仔细认真
这道题还是整了我很久,真的不太 清楚别人到底是怎么想出来的,反正我是无能为力了。还是先学习这把,突然让我心里升起了征服的欲望
还是回头继续说这道题把,关于线段树的优点不言而喻了,把整个大区间分成了一个一个的小区间,这道题恰好利用了这个性质,更改的时候整个区间一块更改了
这里的标记兼价值flag很有意思,这样来解释下把,初始化为1,当线段树中的父节点的所有子节点的flag都一样时,父节点的flag为1(2,3),否则为-1,
更改的时候,若父节点的所有子节点的flag一样,则父节点的flag不为-1(可能为1,2,3),否则标记为-1
查询的时候只查询记录那些flag为1的节点,不为1的则没有什么价值
下面贴出代码,刚开死根本update(),和query()根本看不懂,还是debug了一下,然后豁然开朗
1 #include <stdio.h> 2 #include <cstring> 3 int a[100005]; 4 struct node 5 { 6 int left; 7 int right; 8 int flag; 9 }; 10 node tree[100005*4]; 11 int n; 12 int sum; 13 14 15 void build (int left,int right,int root) 16 { 17 tree[root].left=left; 18 tree[root].right=right; 19 tree[root].flag=1;//表示在这个区间内的点都是1 level的 20 if(left==right) 21 { 22 return;//这里刚开始忘了return,唉,爆栈了 23 } 24 int mid=(left+right)/2; 25 build(left,mid,root*2); 26 build(mid+1,right,root*2+1); 27 } 28 29 30 void update(int left,int right,int root,int level) 31 { 32 if(tree[root].right<left || tree[root].left > right )//完全不在区间内 33 { 34 return ; 35 } 36 if(tree[root].left>=left && tree[root].right<=right)//完全在区间内 37 { 38 tree[root].flag=level; 39 return; 40 } 41 if(tree[root].flag!=-1)//只有一部分在区间内,所以这个范围内的数据时脏的 42 { 43 tree[root*2].flag=tree[root].flag; 44 tree[root*2+1].flag=tree[root].flag; 45 tree[root].flag=-1;//标记这个父节点,表示其子节点中有脏数据 46 } 47 update(left,right,root*2,level); 48 update(left,right,root*2+1,level); 49 } 50 51 52 void query(int root) 53 { 54 if(tree[root].flag!=-1) 55 { 56 sum=sum+tree[root].flag*(tree[root].right-tree[root].left+1); 57 return ;//递归的时候一定要注意返回 58 } 59 if(tree[root].left==tree[root].right)//查询到子节点要返回,否则一直递归下去,递归的时候注意什么时候返回,重要 60 { 61 return ; 62 } 63 query(root*2); 64 query(root*2+1); 65 } 66 67 int main() 68 { 69 int Case,q; 70 int start,end,level; 71 scanf("%d",&Case); 72 int k=1; 73 while(Case--) 74 { 75 scanf("%d%d",&n,&q); 76 build(1,n,1); 77 while(q--) 78 { 79 scanf("%d%d%d",&start,&end,&level); 80 update(start,end,1,level); 81 } 82 sum=0; 83 query(1); 84 printf("Case %d: The total value of the hook is %d.\n",k++,sum); 85 } 86 return 0; 87 }
唉,征服的欲望啊