标签:线段树
核心思想就是节点上记录最大值和最小值,如果max<p或min>=p时,只在节点改变add值,不用往子树遍历;否则就往子树进行递归。
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<vector> using namespace std; const int maxn = 2e5+50; int N, P; struct node{ int l, r, Min, Max, add; int mid() { return (l+r)/2; } }tree[maxn<<2]; int p, n; void buildTree(int l, int r, int rt) { tree[rt].l = l; tree[rt].r = r; tree[rt].add = 0; tree[rt].Min = 0; tree[rt].Max = 0; if(l == r) return ; int mid = tree[rt].mid(); buildTree(l, mid, rt<<1); buildTree(mid+1, r, rt<<1|1); } void update(int l, int r, int rt, int L, int R, int add) { if(L <= l && R >= r) { if(tree[rt].Max < P) { tree[rt].add += add; tree[rt].Min += add; tree[rt].Max += add; return ; } else if(tree[rt].Min >= P) { tree[rt].add += 2*add; tree[rt].Min += 2*add; tree[rt].Max += 2*add; return ; } } if(tree[rt].add){ tree[rt<<1].add += tree[rt].add; tree[rt<<1].Min += tree[rt].add; tree[rt<<1].Max += tree[rt].add; tree[rt<<1|1].add += tree[rt].add; tree[rt<<1|1].Min += tree[rt].add; tree[rt<<1|1].Max += tree[rt].add; tree[rt].add = 0; } if(l == r) return ; int mid = tree[rt].mid(); if(L <= mid) update(l, mid, rt<<1, L, R, add); if(R > mid) update(mid+1, r, rt<<1|1, L, R, add); tree[rt].Min = min(tree[rt<<1].Min, tree[rt<<1|1].Min); tree[rt].Max = max(tree[rt<<1].Max, tree[rt<<1|1].Max); } void query(int l, int r, int rt) { if(tree[rt].Min == tree[rt].Max){ for(int i = l; i <= r; i ++) printf( i == N ? "%d\n" : "%d ", tree[rt].Min ); return ; } if(tree[rt].add) { tree[rt<<1].add += tree[rt].add; tree[rt<<1].Min += tree[rt].add; tree[rt<<1].Max += tree[rt].add; tree[rt<<1|1].add += tree[rt].add; tree[rt<<1|1].Min += tree[rt].add; tree[rt<<1|1].Max += tree[rt].add; tree[rt].add = 0; } if(l == r) return ; int mid = tree[rt].mid(); query(l, mid, rt<<1); query(mid+1, r, rt<<1|1); } int main() { int n, m, p; int a, b, c; while(~scanf("%d%d%d", &n, &m, &p)) { N = n; P = p; buildTree(1, n, 1); for(int i = 0; i < m; i ++) { scanf("%d%d%d", &a, &b, &c); update(1, n, 1, a, b, c); } query(1, n, 1); } }
标签:线段树
原文地址:http://blog.csdn.net/u011504498/article/details/38111217