/*题意:输入一个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;
}
Just a Hook (线段树)
最新推荐文章于 2021-11-15 22:13:06 发布