标签:poj 2777 count color 线段树成段更新 延迟标记 二进制表示
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
有两种方法:一种是每次查询时都要统计对应区间延迟标记上颜色的种类,可以用set或简单哈希来实现。
一种是用二进制表示对应的区间涂了第几种颜色,这样每个区间除了延迟标记外,可以再开一个数组统计当前涂了哪几种颜色。这样就和一般的线段树一样了。
最后再统计一下1的数目。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 100005
#define inf 0x3f3f3f3f
typedef long long LL;
int sum[maxn<<2],col[maxn<<2],ll[maxn<<2],rr[maxn<<2];
inline void pushup(int i){
sum[i]=sum[i<<1]|sum[i<<1|1];
}
inline void pushdown(int i){
if(col[i]){
col[i<<1]=col[i<<1|1]=col[i];
sum[i<<1]=col[i];
sum[i<<1|1]=col[i];
col[i]=0;
}
}
void build(int l,int r,int i){
ll[i]=l;
rr[i]=r;
col[i]=1;
if(l==r)return;
int m=(ll[i]+rr[i])>>1,ls=i<<1,rs=ls|1;
build(l,m,ls);
build(m+1,r,rs);
pushup(i);
}
void update(int l,int r,int v,int i){
if(l<=ll[i]&&rr[i]<=r){
col[i]=1<<(v-1);
sum[i]=col[i];
return ;
}
pushdown(i);
int m=(ll[i]+rr[i])>>1,ls=i<<1,rs=ls|1;
if(l<=m)update(l,r,v,ls);
if(m<r)update(l,r,v,rs);
pushup(i);
}
int query(int l,int r,int i){
if(l<=ll[i]&&rr[i]<=r){
return sum[i];
}
pushdown(i);
int m=(ll[i]+rr[i])>>1,ls=i<<1,rs=ls|1;
int ans=0;
if(l<=m)ans=ans|query(l,r,ls);
if(m<r)ans=ans|query(l,r,rs);
return ans;
}
int main()
{
int l,t,o,a,b,c;
char q[2];
//freopen("in.txt","r",stdin);
while(~scanf("%d%d%d",&l,&t,&o)){
build(1,l,1);
for(int i=0;i<o;i++){
scanf("%s%d%d",q,&a,&b);
if(a>b)swap(a,b);
if(q[0]=='C'){
scanf("%d",&c);
update(a,b,c,1);
}
else {
int res=query(a,b,1);
int ans=0;
while(res){
if(res&1)ans++;
res=res>>1;
}
printf("%d\n",ans);
}
}
}
}#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 100005
#define inf 0x3f3f3f3f
typedef long long LL;
int ll[maxn<<2],rr[maxn<<2],col[maxn<<2],vis[32];
int ans;
inline void pushdown(int i,int m){
if(col[i]){
col[i<<1]=col[i<<1|1]=col[i];
col[i]=0;
}
}
void build(int l,int r,int i){
ll[i]=l;
rr[i]=r;
col[i]=1;
if(l==r){
return ;
}
int m=(ll[i]+rr[i])>>1,ls=i<<1,rs=ls|1;
build(l,m,ls);
build(m+1,r,rs);
}
void update(int l,int r,int v,int i){
if(l<=ll[i]&&rr[i]<=r){
col[i]=v;
return ;
}
pushdown(i,rr[i]-ll[i]+1);
int m=(ll[i]+rr[i])>>1,ls=i<<1,rs=ls|1;
if(l<=m)update(l,r,v,ls);
if(m<r) update(l,r,v,rs);
}
void query(int l,int r,int i){
if(col[i]){
if(!vis[col[i]]){
ans++;
vis[col[i]]=1;
}
return ;
}
pushdown(i,rr[i]-ll[i]+1);
int m=(ll[i]+rr[i])>>1,ls=i<<1,rs=ls|1;
if(l<=m)query(l,r,ls);
if(m<r)query(l,r,rs);
}
int main()
{
int l,t,o,a,b,c;
char q[2];
//freopen("in.txt","r",stdin);
while(~scanf("%d%d%d",&l,&t,&o)){
build(1,l,1);
for(int i=0;i<o;i++){
scanf("%s%d%d",q,&a,&b);
if(a>b)swap(a,b);
if(q[0]=='C'){
scanf("%d",&c);
update(a,b,c,1);
}
else {
ans=0;
memset(vis,0,sizeof vis);
query(a,b,1);
printf("%d\n",ans);
}
}
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:poj 2777 count color 线段树成段更新 延迟标记 二进制表示
原文地址:http://blog.csdn.net/u013497977/article/details/47059759