PKU 2777 Count Color

http://poj.org/problem?id=2777
長さlの板に何回も色を塗っていく。
以下のようなクエリを処理しろといような問題。
区間[a,b]を色cで塗る。
区間[a,b]に何色の色が塗られているか答える。

セグメント木を頑張って書きました。
セグメント木は1色しか塗られていない領域まで深くしていっています。
塗るときに、色が増える場合は、もとあった色を一段下まで塗るようにしています。

int segtree[800000];

int paint(int l,int r,int k,int cl,int cr,int c){
  //cout<<"p "<<l<<' '<<r<<' '<<k<<' '<<cl<<' '<<cr<<' '<<c<<endl;
  if(l<=cl && cr<=r)
    return segtree[k]=c;

  if(cr<=l || r<=cl)return segtree[k];
  if(__builtin_popcount(segtree[k])<=1){
    paint(cl,cr,k*2+1,cl,(cl+cr)/2,segtree[k]);
    paint(cl,cr,k*2+2,(cl+cr)/2,cr,segtree[k]);
  }

  return
    segtree[k]=
    paint(l,r,k*2+1,cl,(cl+cr)/2,c)|
    paint(l,r,k*2+2,(cl+cr)/2,cr,c);
}


int count(int l,int r,int k,int cl,int cr){
  //cout<<"c "<<l<<' '<<r<<' '<<k<<' '<<cl<<' '<<cr<<endl;  
  if(r<=cl || cr<=l)return 0;
  if(l<=cl && cr<=r ||
     __builtin_popcount(segtree[k])<=1)
    return segtree[k];

  return
    count(l,r,k*2+1,cl,(cl+cr)/2)|count(l,r,k*2+2,(cl+cr)/2,cr);
}


main(){
  int l,t,o;
  scanf("%d%d%d",&l,&t,&o);
  int n=1;
  while(n<=l)n<<=1;
  paint(0,n,0,0,n,1);

  while(o--){
    /*
    int idx=0;
    cout<<endl;
    for(int i=1;i<=n;i*=2){
      for(int j=0;j<i;++j)
        printf("%d ",segtree[idx+j]);
      puts("");
      idx+=i;
    }
    cout<<endl;
    */
    char c;
    int a,b;
    scanf(" %c %d %d",&c,&a,&b);
    if(c=='P')
      printf("%d\n",__builtin_popcount(count(a,b+1,0,0,n)));
    else{
      int c;
      scanf("%d",&c);
      paint(a,b+1,0,0,n,1<<c-1);
    }
    //cout<<endl;
  }
}