大概意思就是一开始所有数字为1,然后把一些连续的数字变为一个数,最后求变换完成的数字序列的和。肯定是用线段树做没跑了,然后这个题也是比较简单,建好树之后光维护就行了,不需要查询操作,因为序列最终的和就是树根的值,直接输出就行了。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 1e5+10;
int a[maxn],tree[maxn*4],add[maxn*4];
void Build(int p,int l,int r)
{
if(l == r)
{
tree[p] = 1;
return;
}
int mid = (l + r) / 2;
Build(p * 2,l,mid);
Build(p * 2 + 1,mid + 1,r);
tree[p] = tree[p * 2] + tree[p * 2 + 1];
}
void Push(int p,int l,int r)
{
if(add[p])
{
int mid = (l + r) / 2;
tree[p * 2] = (mid - l + 1) * add[p];
tree[p * 2 + 1] = (r - mid) * add[p];
add[p * 2] = add[p];
add[p * 2 + 1] = add[p];
add[p] = 0;
}
}
void Change(int p,int l,int r,int L,int R,int num)
{
if(L <= l && R >= r)
{
tree[p] = (r - l + 1) * num;
add[p] = num;
return;
}
Push(p,l,r);
int mid = (l + r) / 2;
if(L <= mid)
Change(p * 2,l,mid,L,R,num);
if(R > mid)
Change(p * 2 + 1,mid + 1,r,L,R,num);
tree[p] = tree[p * 2] + tree[p * 2 + 1];
}
int main()
{
int t,cas = 0;
scanf("%d",&t);
while(t--)
{
memset(add,0,sizeof(add));
int n,q;
scanf("%d %d",&n,&q);
Build(1,1,n);
while(q--)
{
int x,y,z;
scanf("%d %d %d",&x,&y,&z);
Change(1,1,n,x,y,z);
}
printf("Case %d: The total value of the hook is %d.\n",++cas,tree[1]);
}
return 0;
}