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;
}

 

posted @ 2022-07-11 17:59  皮卡Q  阅读(29)  评论(0编辑  收藏  举报