Hdu 1698 Just a Hook

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

 题目的题意就是:给你一些牌子(铜,银,金)分别用1,2,3表示,一开始这些都是铜牌。现在对这些区间区间进行操作,比如说将1到5的牌子涂成银牌等等。最后统计这些牌子的总价值。

解题思路:用线段树的思想来做。首先先建立线段树,在涂色的时候,我们只涂到我们所要操作的区间,对于下面的子区间我们不做涂色,当我们当前所访问的区间不是我们所要操作的区间,则要是当前访问的区间的颜色值不为0,则我们要将当前值传递给它的子区间,将当前的改为0就可以了。总之,如果当前的区间的颜色值不为0,则说明当前区间的颜色统一为这个值。否则不是。

参考代码如下:

//线段树题目,题意就是给你一个区间(代表牌子),一开始是铜牌(1代表),然后下面有 //Q个操作,最后问你这个区间到底有多少价值; #include<stdio.h> #include<string.h> #define M 100005 struct node{ int l, r, mid; int color;//本子树所代表的颜色 // int value;//本区间的价值 }t[3*M]; void build(int id, int l, int r) { t[id].l = l; t[id].r = r; t[id].color = 1; // t[id].value = (r-l+1); t[id].mid = (l+r)/2; if(l == r) { // t[id].color = 1; return; } int mid = t[id].mid; build(2*id,l,mid);//建立左子树 build(2*id+1,mid+1,r);//建立右子树 } void update(int id, int l, int r,int c) { if(t[id].l == l && t[id].r == r) { t[id].color = c; // t[id].value = (r-l+1)*c; return; } if(t[id].color != 0)//表明这个区间为统一的颜色值 { t[2*id].color = t[id].color; t[2*id+1].color = t[id].color; t[id].color = 0; } int mid = t[id].mid; if(l > mid) update(2*id+1,l,r,c); else if(r <= mid) update(2*id,l,r,c); else { update(2*id,l,mid,c); update(2*id+1,mid+1,r,c); } // t[id].value = t[id*2].value + t[2*id+1].value; } int query(int id,int l,int r) { if(t[id].color > 0) return t[id].color * (t[id].r - t[id].l + 1); int mid = (t[id].l + t[id].r )/2; if(r <= mid) query(2*id,l,r); else if(l>mid) query(2*id+1,l,r); else { return query(2*id,l,mid)+query(2*id+1,mid+1,r); } } int main() { // freopen("in.txt","r",stdin); int ca, id=1, n, q; scanf("%d",&ca); while(ca--) { scanf("%d",&n); build(1,1,n); scanf("%d",&q); int x, y, z; while(q--) { scanf("%d %d %d",&x, &y, &z); update(1,x,y,z); } printf("Case %d: The total value of the hook is %d./n",id++,query(1,1,n)); } return 0; }

你可能感兴趣的:(c,struct,query,Build,hook)