hdu1698--线段树更新区间

线段树 更新整个区间

不要一直更新到节点,用一个标记值-1标记是否杂色。

更新的时候如果该段正好是要更新的段则将其更新即可。

否则说明要更新的段与当前的tt[step]这一段不一致,则要将tt[step]这一段拆分成2段,递归调用更新step*2及step*2+1,更新后tt[step]将变成杂色。

所以将子段先赋予其父段tt[step]的颜色,并将tt[step]标记为杂色,在递归调用update。

 1 //Accepted 1698 406MS 3308K 1263 B C++ hujj 
 2 #include<iostream>
 3 #include<string>
 4 #define MAX 100010
 5 using namespace std;
 6 int num[MAX];
 7 struct SegTree
 8 {
 9     int left,right,value;
10     int calmid()
11     {
12         return (left+right)/2;
13     }
14 }tt[MAX*3];
15 
16 void bulid(int s,int t,int step)
17 {
18     tt[step].left=s;
19     tt[step].right=t;
20     tt[step].value=1;
21     if(s==t)
22         return ;
23     int mid=tt[step].calmid();
24     bulid(s,mid,step*2);
25     bulid(mid+1,t,step*2+1);
26 }
27 
28 void update(int a,int b,int x,int step)
29 {
30     if(tt[step].value==x)
31         return;
32     if(a<=tt[step].left&&tt[step].right<=b){
33         tt[step].value=x;
34         return;
35     }
36     if(tt[step].value!=-1){
37         tt[step*2].value=tt[step].value;
38         tt[step*2+1].value=tt[step].value;
39         tt[step].value=-1;
40     }
41     int mid=tt[step].calmid();
42     if(a<=mid){
43         update(a,b,x,step*2);
44     }
45     if(b>mid)
46         update(a,b,x,step*2+1);
47 }
48 int query(int step)
49 {
50     if(tt[step].value!=-1)
51         return tt[step].value*(tt[step].right-tt[step].left+1);
52     else return query(step*2)+query(step*2+1);
53 }
54 //void print(int N)
55 //{
56 //    for(int i=1;i<=N;i++)
57 //        cout<<tt[i].left<<" "<<tt[i].right<<" "<<tt[i].value<<endl;
58 //    cout<<endl<<endl;
59 //}
60 int main()
61 {
62     int ncase,N,Q,a,b,c;
63     scanf("%d",&ncase);
64     for(int q=1;q<=ncase;q++){
65         scanf("%d%d",&N,&Q);
66         bulid(1,N,1);    
67         while(Q--){
68             //cin>>a>>b>>c;
69             scanf("%d%d%d",&a,&b,&c);
70             update(a,b,c,1);        
71         }
72         printf("Case %d: The total value of the hook is %d.\n",q,query(1)); 
73         //cout<<"Case "<<q<<": The total value of the hook is "<<query(1,N,1)<<"."<<endl;
74     }
75     return 0;
76 }

hdu用C++编译比用G++快很多,而且本题最好用scanf,可以快一倍的速度。

 

还有一种更快的做法,见帖子  http://www.cppblog.com/zhangwangcz/archive/2011/05/04/145697.html

posted @ 2012-07-13 09:52  HUJJ  阅读(352)  评论(0编辑  收藏  举报