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

你可能感兴趣的:(HDU)