很水的树,第一发竟然re,气的挠头啊......
就是用一个二进制数记录颜色即可..注意懒操作,否则会超时
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define MAX 1000007
using namespace std;
typedef long long LL;
struct Node
{
int l , r;
LL color;
int lazy;
}tree[MAX<<2];
void build ( int u , int left , int right )
{
tree[u].l = left , tree[u].r = right;
tree[u].color = (1<<1);
tree[u].lazy = 0;
if ( left == right ) return;
int mid = left + right >> 1;
build ( u<<1 , left , mid );
build ( u<<1|1 , mid+1 , right );
}
void push_down ( int u )
{
if ( tree[u].lazy )
{
tree[u<<1].color = tree[u].color;
tree[u<<1|1].color = tree[u].color;
tree[u<<1].lazy = tree[u].lazy;
tree[u<<1|1].lazy = tree[u].lazy;
tree[u].lazy = 0;
}
}
void push_up ( int u )
{
tree[u].color = tree[u<<1].color | tree[u<<1|1].color;
}
void update ( int u , int left , int right , int c )
{
int l = tree[u].l , r = tree[u].r;
if ( left <= l && r <= right )
{
tree[u].color = (1<<(c-1));
tree[u].lazy = 1;
return;
}
push_down ( u );
int mid = l + r >> 1;
if ( left <= mid && right >= l ) update ( u<<1 , left , right , c );
if ( left <= r && right > mid ) update ( u<<1|1 , left , right , c);
push_up ( u );
}
LL query ( int u , int left , int right )
{
int l = tree[u].l , r = tree[u].r;
LL ret = 0;
if ( left <= l && r <= right )
return tree[u].color;
int mid = l + r >> 1;
push_down ( u );
if ( left <= mid && right >= l )
ret |= query ( u<<1 , left , right );
if ( left <= r && right > mid )
ret |= query ( u<<1|1 , left, right );
return ret;
}
int n,m;
int main ( )
{
while ( ~scanf ( "%d%d" , &n , &m ) ,n+m )
{
build ( 1 , 1 , n );
char s[2] ;
int l , r , c;
for ( int i = 0 ; i < m ; i++ )
{
scanf ( "%s" , s );
if ( s[0] == 'P' )
{
scanf ( "%d%d%d" , &l , &r , &c );
update ( 1 , l , r , c );
}
else
{
scanf ( "%d%d" , &l , &r );
LL ans = query ( 1 , l , r );
int cnt = 1;
while ( ans%2 == 0 && ans )
{
cnt++;
ans >>= 1;
}
printf ( "%d" , cnt++ );
ans >>= 1;
while ( ans )
{
if ( ans&1 )
printf ( " %d" , cnt );
cnt++;
ans >>= 1;
}
puts ( "" );
}
}
}
}