登 录
第一个线段树,大部分时间都在寒假挥霍了。最近迫切需要女朋友,又没有现成的,又不会找,恰似M67所言:“欲火焚身”那
#include<iostream> using namespace std; const int sup=8010; int ans[sup]; struct node { int left,right; int color; node *rch,*lch; node(int beg,int end) { left=beg; right=end; rch=NULL; lch=NULL; color=-1;//新建节点的区间段初始没有颜色标记 } }; node* creat_tree(int beg,int end) { node* tmp=new node(beg,end); if(end-beg>1) { tmp->lch=creat_tree(beg,(beg&end)+((beg^end)>>1)); tmp->rch=creat_tree((beg&end)+((beg^end)>>1),end); } return tmp; } void insert(node* root,int L,int R,int c) { if(L==root->left && R==root->right || c==root->color)//区间重复或者涂色重复 { root->color=c; return; } if(root->color>=0)//单色,那么子区间也是单色,但由于涂上的新色c不与root区间上任意色重复,故root大区间变成多色,而子区间暂时均为单色 { root->lch->color=root->color; root->rch->color=root->color; } root->color=-2;//变为多色 int mid=(root->left&root->right)+((root->left^root->right)>>1); if(R<=mid) insert(root->lch,L,R,c); else if(L>=mid) insert(root->rch,L,R,c); else { insert(root->lch,L,mid,c); insert(root->rch,mid,R,c); } } void count(node* root,int &c)//计算root区间上颜色c所占的线段数 { if(root->color>=0 && c!=root->color)//单色且root上没有c这种颜色,那么更新c { c=root->color; ++ans[c];//新色新增一个线段 } else if(-2==root->color)//当前大区间段包含多余一种颜色,那么就要细分,去找只包含一种颜色的子线段 { count(root->lch,c); count(root->rch,c); } else c=root->color;//当前区间段还未上色,那么c初始化为空白 } int main() { int n,i; int a,b,c; node* root; while(EOF!=scanf("%d",&n)) { root=creat_tree(0,sup);//初始建立线段树 while(n--) { scanf("%d%d%d",&a,&b,&c); insert(root,a,b,c); } fill(ans,ans+sup,0); int colo=-1;//初始空白 count(root,colo); for(i=0;i<sup;++i) if(ans[i]) printf("%d %d/n",i,ans[i]); printf("/n"); } return 0; }
抱歉!评论已关闭.