1 10 2 1 5 2 5 9 3
Case 1: The total value of the hook is 24.
题目意思:就是给一个n个位置(1~n),刚开始每一个位置价值赋值为1,后来跟新一段的值 例如 1 5 2 表示把1~5的位置全部变成价值为2,最后输出1~n所有位置价值和
不好理解的地方是pushdown()函数,例如输入1,n 2,我标记1到n是一样的价值(f[pos].va=1),又输入1 3 1时,我需要吧
前面的2传递给4到n,再更新1~3
不懂就好好理解吧,都是那么苦逼过来的
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)
using namespace std;
#define N 100005
int a[N];
struct stud{
int le,ri;
int cover;
int va;
}f[N*4];
void pushdown(int pos)
{
if(f[pos].cover)
{
f[L(pos)].va=f[R(pos)].va=f[pos].va;
f[L(pos)].cover=f[R(pos)].cover=1;
f[pos].cover=0;
}
}
void build(int pos,int le,int ri)
{
f[pos].le=le;
f[pos].ri=ri;
f[pos].va=1;
f[pos].cover=1;
if(le==ri) return ;
int mid=MID(le,ri);
build(L(pos),le,mid);
build(R(pos),mid+1,ri);
}
void update(int pos,int le,int ri,int va)
{
if(f[pos].le==le&&f[pos].ri==ri)
{
f[pos].va=va;
f[pos].cover=1;
return ;
}
pushdown(pos);
int mid=MID(f[pos].le,f[pos].ri);
if(mid>=ri)
update(L(pos),le,ri,va);
else
if(mid<le)
update(R(pos),le,ri,va);
else
{
update(L(pos),le,mid,va);
update(R(pos),mid+1,ri,va);
}
}
int query(int pos)
{
if(f[pos].cover)
return f[pos].va*(f[pos].ri-f[pos].le+1);
pushdown(pos);
return query(L(pos))+query(R(pos));
}
int main()
{
int n,m,i,t,ca=0;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
build(1,1,n);
scanf("%d",&m);
int le,ri,va;
while(m--)
{
scanf("%d%d%d",&le,&ri,&va);
update(1,le,ri,va);
}
printf("Case %d: The total value of the hook is %d.\n",++ca,query(1));
}
return 0;
}
HDU 1698 Just a Hook (线段树区间更新)
原文:http://blog.csdn.net/u014737310/article/details/38756665