其实做者道题感觉收获还是蛮大的,因为学会了一个新东西 bitset
1.bitset 总结 http://blog.csdn.net/qll125596718/article/details/6901935
这个博客里面有具体的介绍,讲的非常的详细,其实说白了,bitset就是一个超大的二进制表示状态的特殊集合,因为重载了[ ]符号和 位运算 所以用起来非常的方便,就像一个小数组,除此之外还有
bitset<105>q;//105必须是一个常数
q[ i ] = j //直接可以
q.reset() // 全部清除为 0 q.reset( i ) //把 i 这一个位置清空
q.set() //全部赋值为 1 q.set( i ) //把 i 赋值为1
2.在此题中,返回值必须是bitset<105> 原因自己想
3.线段树的题记住在访问儿子的时候先下放懒惰标记,还要说多少次?可多不要少
#include<cstdio>
#include<iostream>
#include<cstring>
#include<bitset>
#define ls u<<1,l,mid
#define rs u<<1|1,mid+1,r
using namespace std;
int n;
struct node{
int add;
bitset<105>sum;
}nod[400020];
void push_up(int u){nod[u].sum=nod[u<<1].sum|nod[u<<1|1].sum;}
void push_down(int u){
if(!nod[u].add)return ;
int ll=u<<1,rr=u<<1|1;
int add=nod[u].add;
nod[ll].sum.reset();nod[rr].sum.reset();
nod[ll].add=nod[rr].add=add;
nod[ll].sum[add]=1;nod[rr].sum[add]=1;
nod[u].add=0;
}
void build(int u,int l,int r){
if(l==r){
int x;
scanf("%d",&x);
nod[u].sum.reset();nod[u].add=0;
nod[u].sum[x]=1;
return ;
}
int mid=(l+r)>>1;
build(ls);
build(rs);
push_up(u);
return;
}
void update(int u,int l,int r,int x,int y,int add){
if(x==l&&r==y){
nod[u].sum.reset();
nod[u].add=add;
nod[u].sum[add]=1;
return;
}
push_down(u);
int mid=(l+r)>>1;
if(x>mid)update(rs,x,y,add);
else if(y<=mid)update(ls,x,y,add);
else{
update(ls,x,mid,add);
update(rs,mid+1,y,add);
}
push_up(u);
}
bitset<105> query(int u,int l,int r,int x,int y){
if(x==l&&y==r){
return nod[u].sum;
}
push_down(u);
push_up(u);
int mid=(l+r)>>1;
bitset<105>res;
res.reset();
if(x>mid)res|=query(rs,x,y);
else if(y<=mid)res|=query(ls,x,y);
else{
res|=query(ls,x,mid);
res|=query(rs,mid+1,y);
}
return res;
}
int main(){
int w,m;
scanf("%d%d",&n,&w);
build(1,1,n);
scanf("%d",&m);
char s[5];
while(m--){
scanf("%s",s);
int a,b,c;
scanf("%d%d",&a,&b);
if(s[0]=='Q')printf("%d\n",query(1,1,n,a,b).count());
else{
scanf("%d",&c);
update(1,1,n,a,b,c);
}
}
return 0;
}