这两天在练习各种线段树,于是就继续更一道线段树的题目QAQ
题面如下:
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 49616 | Accepted: 14946 |
Description
Input
Output
Sample Input
2 2 4 C 1 1 2 P 1 2 C 2 2 2 P 1 2
Sample Output
2 1
题意:和之前有个贴海报的题差不多,意思就是给你一个区间和一些颜色,区间初始全为颜色1,C操作代表将某一区间涂成某一种颜色,P操作是询问某一区间的颜色个数。
分析:一道比较裸的线段树,在这儿可以稍微用一下lazy标记。有个思想,如何在线段树中体现两个区间不同颜色的个数?我们这儿采用了二进制存储信息的思想,因为它总共只有30发颜色,所以我们用一个int位的二进制表示就足够了。两个区间的不同颜色个数就是把他们或起来就可以了。
这儿注意比较坑的一点是,查询的区间有可能第一个数是大于第二个数的QAQ
代码如下:
#include
#include
#include
#include
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int maxn=1e5+7;
int l,t,o;
int tree[maxn<<2],Hash[maxn],lazy[maxn<<2];
void pushup(int rt){
tree[rt]=tree[rt<<1]|tree[rt<<1|1];
}
void pushdown(int rt){
if(lazy[rt]){
lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
tree[rt<<1]=tree[rt<<1|1]=lazy[rt];
lazy[rt]=0;
}
}
void build(int l,int r,int rt){
tree[rt]=lazy[rt]=0;
if(l!=r){
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
else tree[rt]=1;
}
void update(int L,int R,int c,int l,int r,int rt){
if(L>r||R>1;
update(L,R,c,lson);
update(L,R,c,rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt){
if(L>r||l>R) return 0;
if(L<=l&&r<=R){
return tree[rt];
}
pushdown(rt);
int m=(l+r)>>1;
return query(L,R,lson)|query(L,R,rson);
}
int ans(int c){
int aa=0;
while(c){
if(c&1)
aa++;
c>>=1;
}
return aa;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>l>>t>>o;
build(1,l,1);
char s;
while(o--){
cin>>s;
int x,y,z;
if(s=='C') {
cin>>x>>y>>z;
if(x>y) swap(x,y);
update(x,y,z,1,l,1);
}
else{
cin>>x>>y;
if(x>y) swap(x,y);
cout<