您的位置:首页 > 其它

【线段树】 POJ 2777 Count Color

2014-06-20 16:35 337 查看
简单的线段树,用到位运算,这个题目最大的收获是lazy标记原来在操作有顺序的时候照样可以用。。。。之前不知道。。涨姿势了。

#include <iostream>
#include <sstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <climits>
#define maxn 400005
#define eps 1e-6
#define mod 1000000007
#define INF 99999999
#define lowbit(x) (x&(-x))
typedef long long LL;
using namespace std;

int segtree[maxn];
int mark[maxn];
char s[10];
int n, m, ans;
int qr, ql, k;

void build(int o, int L, int R)
{
if(L==R){
segtree[o]=1;
return;
}
int mid=(L+R)>>1;
build(o<<1, L, mid);
build(o<<1 | 1, mid+1, R);
segtree[o]=segtree[o<<1]|segtree[o<<1 | 1];
}
void pushdown(int o, int L, int R)
{
if(!mark[o]) return;
segtree[o<<1]=mark[o];
segtree[o<<1 | 1]=mark[o];
mark[o<<1]=mark[o];
mark[o<<1 | 1]=mark[o];
mark[o]=0;
}
void query(int o, int L, int R)
{
if(ql<=L && qr>=R){
ans|=segtree[o];
return;
}
pushdown(o, L, R);
int mid=(R+L)>>1;
if(ql<=mid) query(o<<1, L, mid);
if(qr>mid) query(o<<1 | 1, mid+1, R);
segtree[o]=segtree[o<<1]|segtree[o<<1 | 1];
}
void updata(int o, int L, int R)
{
if(ql<=L && qr>=R){
segtree[o]=k;
mark[o]=k;
return;
}
pushdown(o, L, R);
int mid=(R+L)>>1;
if(ql<=mid) updata(o<<1, L, mid);
if(qr>mid) updata(o<<1 | 1, mid+1, R);
segtree[o]=segtree[o<<1]|segtree[o<<1 | 1];
}
void solve(void)
{
int x, tmp;
while(m--){
scanf("%s",s);
if(s[0]=='C'){
scanf("%d%d%d",&ql,&qr,&x);
if(ql>qr) swap(ql, qr);
k=1;
while(--x) k<<=1;
updata(1, 1, n);
}
else{
scanf("%d%d",&ql,&qr);
if(ql>qr) swap(ql, qr);
ans=0;
query(1, 1, n);
tmp=0;
while(ans) tmp+=ans&1, ans>>=1;
printf("%d\n", tmp);
}
}
}
int main(void)
{
while(scanf("%d%*d%d",&n,&m)!=EOF){
build(1, 1, n);
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: