一道线段树的区间修改题,给区间染色,最后输出一个区间的颜色种数,由于颜色不会超过30种,所以可以用int型二进制的每一位表示一种颜色,比如颜色1就是000……0001,颜色3是000……100,那么一个区间内如果有两种颜色A和B,管辖这两个区间的大区间的颜色就为 A|B,最后根据查询到的数得出二进制中1的个数,从而判断出有几种颜色。
写这道题的时候,swap函数出现了一个错误:
swap(int *a,int *b)
int *c
if(*a>*b)
*c=*a;
*a=*b;
*b=*a;
这暴露出我的C语言基础还不扎实,开始声明*c的时候没有赋值,后来又要对这个野指针进行取值,显然是不对的。
#include<stdio.h> #define MAX_LENGTH 100005 struct node { int left; int right; int tag; int color; }board[MAX_LENGTH*4]; void build(int,int,int); void update(int,int,int,int); inline void pushdown(int); inline void pushup(int); inline void swap(int *,int *); int query(int,int,int); inline int calcu(int); int main() { int l,t,o; while(scanf("%d%d%d",&l,&t,&o)!=EOF) { build(1,1,l); int i; for(i=0;i<o;i++) { char ope[2]; scanf("%s",ope); if(ope[0]=='C') { int a,b,c; scanf("%d%d%d",&a,&b,&c); c=1<<(c-1);//将颜色的种类体现在二进制的某一位上 swap(&a,&b); update(1,a,b,c); } else { int a,b,ans; scanf("%d%d",&a,&b); swap(&a,&b); ans=query(1,a,b); ans=calcu(ans); printf("%d\n",ans); } } } return 0; } void build(int root,int le,int ri) { board[root].left=le; board[root].right=ri; board[root].color=1; board[root].tag=0; if(le==ri) return ; int mid=(le+ri)/2; build(2*root,le,mid); build(2*root+1,mid+1,ri); } inline void swap(int *a,int *b) { int c; if(*a>*b) { c=*a; *a=*b; *b=c; } } void update(int root,int le,int ri,int val) { if(le<=board[root].left&&ri>=board[root].right) { board[root].color=val; board[root].tag=val; return ; } if(le>board[root].right||ri<board[root].left) { return ; } pushdown(root); update(2*root,le,ri,val); update(2*root+1,le,ri,val); pushup(root); } inline void pushup(int root) { board[root].color=board[2*root].color|board[2*root+1].color; } inline void pushdown(int root) { if(board[root].tag) { board[root*2].color=board[root].color; board[root*2+1].color=board[root].color; board[root*2].tag=board[root].tag; board[root*2+1].tag=board[root].tag; board[root].tag=0; } } int query(int root,int le,int ri) { if(le<=board[root].left&&ri>=board[root].right) { return board[root].color; } if(le>board[root].right||ri<board[root].left) { return 0; } pushdown(root); pushup(root); return query(2*root,le,ri)|query(2*root+1,le,ri); } inline int calcu(int x) { int ans=0; while(x) { ans+=x&1; x>>=1; } return ans; }