每次操作可以对区间赋值,询问某一区间的值的集合
简单的区间更新
维护 sum[o] 表示该区间值的集合,用二进制表示
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
using namespace std;
#define INF 1e9
#define rep(i,x,y) for(int i=x;i<=y;i++)
#define mset(x) memset(x,0,sizeof(x))
typedef __int64 ll;
const int maxnode = 1000005*4;
char cmd;
int n, m, x1, x2, c, ans;
struct IntervalTree{
int setv[maxnode];
ll sumv[maxnode];
void init(){
memset(setv, -1, sizeof(setv));
mset(sumv);
}
void pushup(int o){
sumv[o] = sumv[2*o+1] | sumv[2*o];
}
void pushdown(int o){
int lc = 2*o+1, rc = o*2;
if(setv[o]>=0){
setv[lc] = setv[rc] = setv[o];
sumv[lc] = sumv[rc] = sumv[o];
setv[o] = -1;
}
}
void update(int o, int L, int R){
int lc=2*o, rc=2*o+1;
if(x1<=L && x2>=R){
setv[o] = c;
sumv[o] = (1<<c);
return;
}
int M = L + (R-L)/2;
pushdown(o);
if(x1<=M) update(lc, L, M);
if(x2>M) update(rc, M+1, R);
pushup(o);
}
void query(int o, int L, int R){
int lc=2*o, rc=2*o+1;
if(x1<=L && x2>=R){
ans |= sumv[o];
return ;
}
pushdown(o);
int M = L + (R-L)/2;
if(x1<=M) query(lc, L, M);
if(x2>M) query(rc, M+1, R);
}
}solve;
int main(){
// freopen("a.txt","r",stdin);
// freopen(".out","w",stdout);
while(cin>>n>>m){
if(n==0 && m==0)
break;
solve.init();
x1=1; x2=n; c=2;
solve.update(1,1,n);
while(m--){
cin>>cmd;
if(cmd=='P'){
scanf("%d%d%d", &x1, &x2, &c);
solve.update(1, 1, n);
}
else{
scanf("%d%d", &x1, &x2);
ans=0;
solve.query(1, 1, n);
int ii=0;
rep(i,1,30){
if((ans>>i)&1){
if(ii) putchar(' ');
printf("%d", i);
ii++;
}
}
puts("");
}
}
}
return 0;
}