Just a Hook
大致题意:
给定一个n, 对于区间[1, n]有如下操作: 选定l, r, 把[l, r]区间全部修改为数值c
最后输出[1, n]的区间和
解题思路:
考察线段树的区间修改 + 根结点查询.
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 1e5+5;
int tree[N<<2],lazy[N<<2];
int n,q;
void Build(int root,int left,int right){
lazy[root] = 0;
if(left==right){
tree[root]=1;
return;
}
int mid,rt;
rt=root<<1;
mid=(left+right)>>1;
Build(rt,left,mid);//最后一个左边递归包含的两个展开的,满足条件的,能完整运行完递归的内容。
Build(rt+1,mid+1,right);//递归到最深层一定是左子叶是left=right=1,右子叶是left=right=2;
tree[root]=tree[rt]+tree[rt+1];
}
void Push_down(int root, int left, int right)
{
int rt=root<<1;
if(lazy[root])
{
lazy[rt] = lazy[root];
lazy[rt+1] = lazy[root];
int mid = (left+right)>>1;
tree[rt] = lazy[root]*(mid-left+1);
tree[rt+1] = lazy[root]*(right-mid);
lazy[root] = 0;
}
}
void Update(int root, int val, int qleft, int qright, int left = 1, int right = n)
{
int rt=root<<1;
int mid = (left+right)>>1;
if(qleft<=left && right <= qright){
tree[root] = (right-left+1)*val;
lazy[root] = val;
return;
}
Push_down(root,left,right);
if(qleft<=mid) Update(rt,val,qleft,qright,left,mid);
if(mid<qright) Update(rt+1,val,qleft,qright,mid+1,right);
tree[root] = tree[rt]+tree[rt+1];
}
int main()
{
int T;
scanf("%d",&T);
for(int t=1;t<=T;t++){
memset(tree,0,sizeof(tree));
scanf("%d %d",&n,&q);
Build(1,1,n);
while(q--){
int x,y,z;
scanf("%d %d %d",&x,&y,&z);
Update(1,z,x,y);
}
printf("Case %d: The total value of the hook is %d.\n",t,tree[1]);
}
return 0;
}