题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698
题目翻译:给出N个位置,开始每个位置都是1,然后给出Q个操作,其格式为A,B,C.
代表把区间【A,B】的值都修改成C,最后求整个区间的和。
AC代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
#define lchild left,mid,root<<1
#define rchild mid+1,right,root<<1|1
using namespace std;
const int maxn = 100100;
int sum[maxn<<2];
int lazy[maxn<<2];
//更新当前接待你
void push_up(int root) {
sum[root] = sum[root<<1] + sum[root<<1|1];
}
//下推标记
void push_down(int left,int right,int root) {
if(lazy[root]) {
lazy[root<<1] = lazy[root];
lazy[root<<1|1] = lazy[root];
int mid = (left+right)>>1;
int leftlen = mid-left+1;
int rightlen = right-mid;
sum[root<<1] = leftlen*lazy[root];
sum[root<<1|1] = rightlen*lazy[root];
lazy[root] = 0;
}
}
//构建线段树
void build(int left,int right,int root) {
lazy[root] = 0;
if(left == right) {
sum[root] = 1;
return;
}
int mid =(left+right)>>1;
build(lchild);
build(rchild);
push_up(root);
}
//区间更新
void update(int L,int R,int num,int left,int right,int root) {
if(L<=left && right<=R) {
sum[root] = (right-left+1)*num;
lazy[root] = num;
return;
}
push_down(left,right,root);
int mid = (left+right)>>1;
if(L<=mid) update(L,R,num,lchild);
if(R>mid) update(L,R,num,rchild);
push_up(root);
}
int main() {
int Case,t=0;
scanf("%d",&Case);
while(Case--) {
int N,Q;
scanf("%d",&N);
memset(sum,0,sizeof(sum));
build(1,N,1);
scanf("%d",&Q);
while(Q--) {
int A,B,C;
scanf("%d%d%d",&A,&B,&C);
update(A,B,C,1,N,1);
}
printf("Case %d: The total value of the hook is %d.\n",++t,sum[1]);
}
return 0;
}