您的位置:首页 > 其它

POJ 2777 线段树

2008-08-02 22:26 197 查看
错误原因:
1. 没有分析清楚什么时候需要向上或者先下传递颜色
2.又把seg[root].l 和 x 搞混淆了

思路:采用线段树来处理,节点的成员c用来记录颜色,采用位运算来处理,有30种颜色,二进制位从右往左数第k位表示有无颜色,那么可以用与运算 | 来合并颜色;成员same表示节点所表示区间颜色是否一样,加入same后可以在log(n)时间内实现线段树的insert和query操作。insert时要注意如果区间颜色一样,那么左右子树的颜色也一样,要在insert时传递下去

/*

PROG:

LANG: C++

ID: heben991

*/

// algorihm:

#include <iostream>

#include <algorithm>

#include <vector>

#include <string>

#include <cctype>

#include <queue>

/*

#include <list>

#include <stack>

#include <set>

#include <map>

#include <cmath>

*/

using namespace std;

#define ma(a,b) (a)>(b)?(a):(b)

#define mi(a,b) (a)<(b)?(a):(b)

#define FF(i,a,b) for(int i=(a);i<=(b);i++)

#define RR(i,b) for(int i=(0);i<(b);i++)

#define clr(x) memset(x,0,sizeof(x))

#define pb push_back

#define mp make_pair

#define sz size()

#define F first

#define S second

#define vv vector

#define ii iterator

/*

#include <sstream>

#include <iterator>

#define ssm stringstream

*/

#define cn continue

#define br break

typedef int type;

const int ST = 0;

#define out(x) cout << #x << "=" << x << endl

template <class T> void show(T a, int n) { for (int i = ST; i < ST+n; i++) { cout<<a[i]<<' '; } cout<<endl; }

template <class T> void show(T a, int r, int l) { for (int i = ST; i < ST+r; i++) show(a[i], l); cout<<endl; }

const int N=110000,M=100000;

struct node

{

int l,r,c;

bool same;

};

node seg[4*N];

int l, t, o;

void build(int root, int x, int y)

{

int len=y-x+1;

int mid=(x+y)/2;

seg[root] = (node) { x,y,1,1};

if(len>1)

{

build(root*2,x,mid);

build(root*2+1,mid+1,y);

}

}

void insert(int root, int x, int y, int color)

{

int mid=(seg[root].l+seg[root].r)/2;

if(x<=seg[root].l && y>=seg[root].r)

{

seg[root].c = 1<<(color-1);

seg[root].same = 1;

}

else

{

if(seg[root].same)

{

seg[root*2].same = seg[root*2+1].same = 1;

seg[root*2].c = seg[root*2+1].c = seg[root].c;

}

if(x<=mid)insert(root*2,x,y,color);

if(y>mid)insert(root*2+1,x,y,color);

seg[root].c = seg[root*2].c | seg[root*2+1].c;

seg[root].same = 0;

}

}

/*

10 5 8

C 1 9 2

C 3 8 3

P 1 10

2

*/

int query(int root, int x, int y)

{

int mid=(seg[root].r+seg[root].l)/2;

if(seg[root].same)return seg[root].c;

if(x<=seg[root].l && y>=seg[root].r)

{

return seg[root].c;

}

{

int ls=0,rs=0;

if(x<=mid)ls = query(root*2,x,y);

if(y>mid)rs = query(root*2+1,x,y);

return ls | rs;

}

}

int count(int x)

{

int ret=0;

//printf("%x ", x);

while(x>0)

{

ret += x & 1;

x>>=1;

}

//printf("%d/n", ret);

return ret;

}

int main()

{

char s[10];

int a, b, c;

scanf("%d%d%d", &l, &t, &o);

//printf("%d %d %d/n", l, t, o);

build(1,1,M);

while(o--)

{

scanf("%s%d%d", s, &a, &b);

//printf("%s %d %d/n", s, a, b);

if(a>b) swap(a,b);

if(s[0]=='C')

{

scanf("%d", &c);

insert(1,a,b,c);

}

else

{

printf("%d/n", count(query(1,a,b)));

}

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: