【线段树 成段更新 lazy标记】LOJ 1164_C/C++_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > C/C++ > 【线段树 成段更新 lazy标记】LOJ 1164

【线段树 成段更新 lazy标记】LOJ 1164

 2012/1/31 9:21:52  基德KID.1412  程序员俱乐部  我要评论(0)
  • 摘要:KIDx的解题报告题目链接:http://lightoj.com/volume_showproblem.php?problem=1164题意:区间内初始时全部为0命令1:0xyv;从x到y全部+v命令2:1xy;输出x到y的值的总和典型lazy的应用#include<iostream>#include<fstream>#include<algorithm>#include<string>#include<set>#include<
  • 标签:线段树 成段更新

KIDx的解题报告

?

题目链接:http://lightoj.com/volume_showproblem.php?problem=1164

?

题意:区间内初始时全部为0

命令1:0 x y v; 从x到y全部+v

命令2:1 x y; 输出x到y的值的总和

典型lazy的应用

#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <utility>
#include <iomanip>
#include <stack>
#include <list>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <ctype.h>
using namespace std;
#define inf 0x3fffffff
#define M 100005
#define LL long long
#define Max 26

struct Node{
	int l, r;			//sum是l到r的总和
	LL v, sum;			//v积累要加的数,需要往下时才更新儿子:lazy标记
}N[M<<2];

void create (int u, int a, int b)
{
	N[u].l = a, N[u].r = b, N[u].v = N[u].sum = 0;
	if (a == b) return ;
	int mid = (a + b) >> 1, lc = u+u, rc = lc+1;
	create (lc, a, mid);
	create (rc, mid+1, b);
}

void update (int u, int a, int b, LL c)
{
	if (a <= N[u].l && b >= N[u].r)
	{
		N[u].v += c;
		N[u].sum += c * (N[u].r-N[u].l+1);		//注意积累是用+=
		return ;
	}
	int lc = u+u, rc = lc+1;
	if (N[u].v > 0)			//lazy一下,需要访问我儿子,我才去更新
	{
		N[lc].v += N[u].v;
		N[lc].sum += N[u].v * (N[lc].r-N[lc].l+1);
		N[rc].v += N[u].v;
		N[rc].sum += N[u].v * (N[rc].r-N[rc].l+1);
		N[u].v = 0;
	}
	if (a <= N[lc].r)
		update (lc, a, b, c);
	if (b >= N[rc].l)
		update (rc, a, b, c);
	N[u].sum = N[lc].sum + N[rc].sum;
}

LL find (int u, int a, int b)?//和比较大,要用long long
{
	if (a <= N[u].l && b >= N[u].r)
		return N[u].sum;
	LL m1 = 0, m2 = 0;
	int lc = u+u, rc = lc+1;
	if (N[u].v > 0)			//同理lazy一下
	{
		N[lc].v += N[u].v;
		N[lc].sum += N[u].v * (N[lc].r-N[lc].l+1);
		N[rc].v += N[u].v;
		N[rc].sum += N[u].v * (N[rc].r-N[rc].l+1);
		N[u].v = 0;
	}
	if (a <= N[lc].r)
		m1 = find (lc, a, b);
	if (b >= N[rc].l)
		m2 = find (rc, a, b);
	return m1+m2;
}

int main()
{
	LL c;
	int t, cc = 1, n, q, k, a, b;
	scanf ("%d", &t);
	while (t--)
	{
		scanf ("%d%d", &n, &q);
		create (1, 1, n);
		printf ("Case %d:\n", cc++);
		while (q--)
		{
			scanf ("%d%d%d", &k, &a, &b);
			a++, b++;
			if (k) printf ("%lld\n", find (1, a, b));
			else scanf ("%lld", &c), update (1, a, b, c);
		}
	}
    return 0;
}

?

发表评论
用户名: 匿名