[HihoCoder]#1078 : 线段树的区间修改
2017-06-01 23:28
399 查看
华电北风吹
日期:2017-06-01
题目链接:
http://hihocoder.com/problemset/problem/1078
题目分析:
不得不说模板代码采用了自顶向下的思路计算量就是小。模板代码思路,对于每个节点,如果整个区间值一致的话,更新和查找到此就直接返回了,不对子树进行更新,不过要保存个lazy属性,以后如果更新或者查询需要进入到区间树子节点的时候,可以凭lazy属性知道里面的值需要pushdown。
模板代码:
自己代码(超时):
日期:2017-06-01
题目链接:
http://hihocoder.com/problemset/problem/1078
题目分析:
不得不说模板代码采用了自顶向下的思路计算量就是小。模板代码思路,对于每个节点,如果整个区间值一致的话,更新和查找到此就直接返回了,不对子树进行更新,不过要保存个lazy属性,以后如果更新或者查询需要进入到区间树子节点的时候,可以凭lazy属性知道里面的值需要pushdown。
模板代码:
#include <iostream> using namespace std; const int maxn = 100100; struct node { int left; int right; int lazy; int sum; }; node data[maxn << 2]; void build(int i, int left, int right) { data[i].left = left; data[i].right = right; data[i].lazy = 0; if(left == right){ scanf("%d",&data[i].sum); return; } int mid = (left + right) >> 1; build(i << 1, left, mid); build(i << 1 | 1, mid + 1, right); data[i].sum = data[i << 1].sum + data[i << 1 | 1].sum; } void pushdown(int v) { if(data[v].lazy){ data[v << 1].sum = (data[v << 1].right - data[v << 1].left + 1) * data[v].lazy; data[v << 1 | 1].sum = (data[v << 1 | 1].right - data[v << 1 | 1].left + 1) * data[v].lazy; data[v << 1].lazy = data[v << 1 | 1].lazy = data[v].lazy; data[v].lazy = 0; } } void update(int v, int left, int right, int val){ if(data[v].left >= left && data[v].right <= right){ data[v].sum = (data[v].right - data[v].left + 1) * val; data[v].lazy = val; return; } pushdown(v); if(left <= data[v << 1].right) update(v << 1, left, right, val); if(right >= data[v << 1 | 1].left) update(v << 1 | 1, left, right, val); data[v].sum = data[v << 1].sum + data[v << 1 | 1].sum; } int query(int v, int left,int right){ if(data[v].left >= left && data[v].right <= right) return data[v].sum; pushdown(v); int a = 0, b = 0; if(left <= data[v << 1].right) a = query(v << 1, left, right); if(right >= data[v << 1 | 1].left) b = query(v << 1 | 1, left, right); data[v].sum = data[v << 1].sum + data[v << 1 | 1].sum; return a + b; } int main() { int n,q,op,a,b,val; while(~scanf("%d",&n)){ build(1, 1, n); scanf("%d",&q); while(q--){ scanf("%d %d %d", &op, &a, &b); if(op){ scanf("%d",&val); update(1, a, b, val); }else printf("%d\n",query(1, a, b)); } } return 0; }
自己代码(超时):
#include <stdio.h> #include <algorithm> using namespace std; #define INT_MAX 0x7fffffff struct node { int leftID, rightID; int sum; }; node data[4000000 + 10]; int father[1000000 + 2]; void Build(int i, int left, int right) { int middle = (left + right) >> 1; data[i].leftID = left; data[i].rightID = right; data[i].sum = 0; if (left == right){ father[left] = i; return; } Build(i << 1, left, middle); Build(i << 1 | 1, middle + 1, right); } void Update(int id, int offset) { data[id].sum += offset; if (id == 1){ return; } Update(id >> 1, offset); } int Query(int i, int l, int r) { int result = 0; if (data[i].leftID == l&&data[i].rightID == r){ return data[i].sum; } int middle = (data[i].leftID + data[i].rightID) >> 1; if (l <= middle){ if (r <= middle){ return Query(i << 1, l, r); }else{ result += Query(i << 1, l, middle); } } if (r >= middle + 1){ if (l >= middle + 1){ return Query(i << 1 | 1, l, r); }else{ result += Query(i << 1 | 1, middle + 1, r); } } return result; } int main() { int n, m; int temp; scanf("%d", &n); Build(1, 1, n); for (int i = 1; i <= n; i++){ scanf("%d", &temp); Update(father[i], temp); } scanf("%d", &m); int flag, left, right, val; for (int i = 0; i<m; i++){ scanf("%d", &flag); if (flag == 0){ scanf("%d%d", &left, &right); int result = Query(1, left, right); printf("%d\n", result); }else{ scanf("%d%d%d", &left, &right, &val); for(int j = left; j <= right; j++){ Update(father[j], val - data[father[j]].sum); } } } return 0; }
相关文章推荐
- hihocoder1078 线段树的区间修改
- hihocoder 1078 : 线段树的区间修改
- hihocoder 1078 线段树的区间修改 (线段树 区间更新 模板)
- hihoCoder 1078 : 线段树的区间修改
- hihocoder 1078 线段树的区间修改线段树(区间修改 区间求和)
- hihoCoder 1078 线段树的区间修改
- hihocoder1078线段树修改区间查询区间(懒标记)
- hihoCoder 1078 线段树的区间修改
- hihocoder 1078 线段树的区间修改 java实现
- hihoCoder 1078 : 线段树的区间修改
- hihocoder 1078 线段树的区间修改
- hiho #1078 : 线段树的区间修改
- HIHO #1078 : 线段树的区间修改
- hihoCoder 1077 RMQ问题再临-线段树 单点修改,求区间最小值
- hihocoder 1078# 线段树的区间修改模版
- hihocoder 1080 更为复杂的买卖房屋姿势(线段树经典操作,区间修改,add+set标记)
- hiho一下第二十周 #1078 : 线段树的区间修改 【线段树】
- hiho1078 线段树的区间修改
- hihoCoder #1078 : 线段树的区间修改(线段树区间更新板子题)
- hihocoder #1078 : 线段树的区间修改