线段树 更新整个区间
不要一直更新到节点,用一个标记值-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