HDU——1698(线段树区间修改模板题)Just a Hook

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698

题意:有一个挂钩是由连续金属棒组成,金属棒编号为1~n,我们会进行若干的区间替换操作,问最后的金属棒总和价值是多少?

解题思路:这是一个典型的区间修改问题,我们按模板写就行,要注意的是这里是对金属棒进行替换,所以我们修改的时候一定要替换而不是相加,具体看代码。
PS:此道题我们甚至都不需要QueryTree函数,因为我们要的就是根节点,但我这里还是写了。

AC代码:

#include

#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll>  pll;
typedef pair<int, int> pii;
const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 1e5+5;//最大值。
//****************分割线,以上为自定义代码模板*****************//


struct node{
	int l,r,lazy;//左右端点和懒惰标记。
	ll sum;
}SegTree[maxn<<2];
void BuildTree(int rt,int l,int r){
	SegTree[rt].l=l;SegTree[rt].r=r;
	SegTree[rt].lazy=0;
	if(l==r){
		SegTree[rt].sum=1;
		return;
	}
	BuildTree(rt<<1,l,(l+r)>>1);
	BuildTree(rt<<1|1,((l+r)>>1)+1,r);
	SegTree[rt].sum=SegTree[rt<<1].sum+SegTree[rt<<1|1].sum;
}
void PushDown(int rt){
	if(SegTree[rt].lazy){
		SegTree[rt<<1].lazy=SegTree[rt].lazy;
		SegTree[rt<<1|1].lazy=SegTree[rt].lazy;
		SegTree[rt<<1].sum=(SegTree[rt<<1].r-SegTree[rt<<1].l+1)*SegTree[rt].lazy;
		SegTree[rt<<1|1].sum=(SegTree[rt<<1|1].r-SegTree[rt<<1|1].l+1)*SegTree[rt].lazy;
		SegTree[rt].lazy=0;
	}
}
void UpDate(int rt,int c,int l,int r){
	if(SegTree[rt].l==l&&SegTree[rt].r==r){
		SegTree[rt].sum=(SegTree[rt].r-SegTree[rt].l+1)*c;
		SegTree[rt].lazy=c;
		return;
	}
	PushDown(rt);
	int mid=(SegTree[rt].l+SegTree[rt].r)>>1;
	if(r<=mid){
		UpDate(rt<<1,c,l,r);//全部在左子树。
	}
	else if(l>mid){
		UpDate(rt<<1|1,c,l,r);//全部在右子树。
	}
	else{
		UpDate(rt<<1,c,l,mid);
		UpDate(rt<<1|1,c,mid+1,r);
	}
	SegTree[rt].sum=SegTree[rt<<1].sum+SegTree[rt<<1|1].sum;
}
ll QueryTree(int rt,int l,int r){
	if(SegTree[rt].l==l&&SegTree[rt].r==r){
		return SegTree[rt].sum;
	}
	PushDown(rt);
	int mid=(SegTree[rt].l+SegTree[rt].r)>>1;
	ll ans=0;
	if(r<=mid){
		ans+=QueryTree(rt<<1,l,r);//全部在左子树。
	}
	else if(l>mid){
		//全部在右子树。
		ans+=QueryTree(rt<<1|1,l,r);
	}
	else{
		ans+=QueryTree(rt<<1,l,mid);
		ans+=QueryTree(rt<<1|1,mid+1,r);
	}
	return ans;
}
int main(){
	//freopen("in.txt", "r", stdin);//提交的时候要注释掉
	IOS;
	int n,q,t;
	while(cin>>t){
		rep(i,1,t){
			cin>>n;
			BuildTree(1,1,n);
			cin>>q;
			int x,y,z;
			while(q--){
				cin>>x>>y>>z;
				UpDate(1,z,x,y);
			}
			printf("Case %d: The total value of the hook is %lld.\n",i,SegTree[1].sum);
		}
	}
	return 0;
}

你可能感兴趣的:(线段树专题,HDU)