您的位置:首页 > 其它

HDU 1698 Just a Hook [线段树-成段更新]

2011-10-04 10:24 344 查看
题意:

屠夫的钩子,可以理解成一条线段,[x,y]是某种颜色,铜色的价值是1,银色是2,金色是3,经过一系列的更新操作,求总的value

分析:

参考比人的,第一次做线段树,找点感觉

记录每个区间是否为纯色,即cover,1为纯色,0为混合色

//AC CODE:

#include<iostream>
#include<cstdio>
using namespace std;

const int MAXN=300005;

struct Node
{
int left,right;
int value;  //用来记录每个节点的值
int isCover; //用来标记是否已经修改过
}tree[MAXN];

void MakeTree(int l,int r,int num)//建树
{
int mid;
tree[num].left=l;
tree[num].right=r;
tree[num].value=1;
tree[num].isCover=1;

if(l==r)  //点树
return;

mid=(l+r)>>1;
MakeTree(l,mid,num*2);//递归的建左子树树
MakeTree(mid+1,r,num*2+1);//递归的建右子树
}

void modify(int x,int y,int z,int num)//更新
{
if(x==tree[num].left && y==tree[num].right)
{
tree[num].value=z;  //赋值
tree[num].isCover=1;  //标记是否被修改
return;
}

if(tree[num].isCover)
{
tree[num].isCover=0;
tree[2*num].value=tree[num].value;
tree[2*num].isCover=1;
tree[2*num+1].value=tree[num].value;
tree[2*num+1].isCover=1;
}

if(y<=tree[2*num].right)
modify(x,y,z,2*num);
else if(x>=tree[2*num+1].left)
modify(x,y,z,2*num+1);
else
{
modify(x,tree[2*num].right,z,2*num);
modify(tree[2*num+1].left,y,z,2*num+1);
}
}

int Query(int num)//查询
{
if(tree[num].isCover)
return tree[num].value*(tree[num].right-tree[num].left+1);
else
return Query(2*num)+Query(2*num+1);
}

int main()
{
//freopen("in.txt","r",stdin);
int test;
int n,q;
int x,y,z;
int i=1;

scanf("%d",&test);
for(i=1; i<=test; i++)
{
scanf("%d",&n);
scanf("%d",&q);
MakeTree(1,n,1); //建树(1 to n)
while(q--)
{
scanf("%d %d %d",&x,&y,&z);
modify(x,y,z,1);
}
printf("Case %d: The total value of the hook is %d.\n",i,Query(1));
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: