Just a Hook (线段树)

/*题意:输入一个T表示有几组测试数据
输入n表示有几块sticks
输入k表示有几次操作
a,b,c表示把区间[a,b]的值改成c
求最后区间[1,n]所有值的和*/


#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;

struct node
{
	int l, r, sum;
	int mark;
}dp[100005<<2];

void Create(int l, int r, int i)
{
	dp[i].l = l;
	dp[i].r = r;
	dp[i].sum = 1;
	dp[i].mark = 0;
	if (l == r)
	{
		dp[i].sum = 1;
		return;
	}
	int mid = (l + r) >> 1;
	Create(l, mid, i * 2);
	Create(mid + 1, r, i * 2 + 1);
	dp[i].sum = dp[i * 2].sum + dp[i * 2 + 1].sum;
}

void Pushdow(int i)
{
	dp[i * 2].sum = (dp[i * 2].r - dp[i * 2].l + 1)*dp[i].mark;
	dp[i * 2].mark = dp[i].mark;//错误点  之前是+=现在改成=就AC了
	dp[i * 2 + 1].sum = (dp[i * 2 + 1].r - dp[i * 2 + 1].l + 1)*dp[i].mark;
	dp[i * 2 + 1].mark = dp[i].mark;//错误点  之前是+=现在改成=就AC了
	dp[i].mark = 0;
}

void Change(int l, int r, int x, int i)//将l-r区间修改为x
{

	if (dp[i].l == l&&dp[i].r == r)
	{
		dp[i].sum = (dp[i].r - dp[i].l + 1)*x;
		dp[i].mark = x;//错误点  之前是+=现在改成=就AC了
		return;
	}
	if (dp[i].mark)
	{
		Pushdow(i);
	}
	int mid = (dp[i].l + dp[i].r) >> 1;
	if (r <= mid)
	{
		Change(l, r, x, i * 2);
	}
	else if (l > mid)
	{
		Change(l, r, x, i * 2 + 1);
	}
	else
	{
		Change(l, mid, x, i * 2);
		Change(mid + 1, r, x, i * 2 + 1);
	}
	dp[i].sum = dp[i * 2].sum + dp[i * 2 + 1].sum;
}

int Find(int l, int r, int i)
{
	if (l == dp[i].l&&r == dp[i].r)
	{
		return dp[i].sum;
	}
	if (dp[i].mark)//错误点     忘了向下压
		Pushdow(i);
	int mid = (dp[i].l + dp[i].r) >> 1;
	if (r <= mid)
	{
		return Find(l, r, i * 2);
	}
	else if (l > mid)
	{
		return Find(l, r, i * 2 + 1);
	}
	else
	{
		return Find(l, mid, i * 2) + Find(mid + 1, r, i * 2 + 1);
	}
}


int main()
{
	int T;
	cin >> T;
	int count = 1;
	while (T--)
	{
		int n;
		cin >> n;
		Create(1, n, 1);
		int k;
		cin >> k;
		for (int i = 0; i < k; i++)
		{
			int a, b, c;
			scanf("%d%d%d", &a, &b, &c);
			//坑点  a有可能比b大,QAQ,wrong了两道
			if (a > b)
			{
				swap(a, b);
			}
			Change(a, b, c, 1);
		}
		printf("Case %d: The total value of the hook is %d.\n", count++, Find(1, n, 1));
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值