poj 2777(线段树)
2013-07-22 14:54
267 查看
这道题是看了别人的思路才做出来的。
刚看完这道题没什么思路,线段的长度是10^5,操作指令数是10^5,还要记录不同颜色种类数,觉着怎么写肯定都是要超时。我当时在节点里增加了一个数组记录已经出现的颜色数,硬着头皮写了一个代码,提交后无悬念TLE。后来又想着单纯的做一个延迟标记,让更新的节点效率达到最高,访问的话直接在一次访问中访问所有的叶节点,这样的话相当于增加了查询的消耗,降低了更新的消耗。想了想,觉得这样虽然能提高不少效率,但是离能过还有段儿距离。
我去看了一下别人的代码,看到这个思路,这个思路跟我第二次的想法有点儿类似,不过做了一个很强大的优化,如果节点中的num是-1的话,表示在这个节点下面有多种颜色,需要往下查询,如果num不为-1,则这个节点下面只有一种颜色,颜色的值即num的值。
非常精彩的优化。
刚看完这道题没什么思路,线段的长度是10^5,操作指令数是10^5,还要记录不同颜色种类数,觉着怎么写肯定都是要超时。我当时在节点里增加了一个数组记录已经出现的颜色数,硬着头皮写了一个代码,提交后无悬念TLE。后来又想着单纯的做一个延迟标记,让更新的节点效率达到最高,访问的话直接在一次访问中访问所有的叶节点,这样的话相当于增加了查询的消耗,降低了更新的消耗。想了想,觉得这样虽然能提高不少效率,但是离能过还有段儿距离。
我去看了一下别人的代码,看到这个思路,这个思路跟我第二次的想法有点儿类似,不过做了一个很强大的优化,如果节点中的num是-1的话,表示在这个节点下面有多种颜色,需要往下查询,如果num不为-1,则这个节点下面只有一种颜色,颜色的值即num的值。
非常精彩的优化。
#include<stdio.h> #include<string.h> #define N 100005 struct node { int x,y; int num; }a[N*3]; int mark[35]; void CreatTree(int t,int x,int y) { a[t].x=x; a[t].y=y; a[t].num=1; if(x==y) return ; int temp=t*2; int mid=(x+y)/2; CreatTree(temp,x,mid); CreatTree(temp+1,mid+1,y); return ; } void InsertTree(int t,int x,int y,int k) { if(a[t].x==x&&a[t].y==y) { a[t].num=k; return ; } int temp=t*2; int mid=(a[t].x+a[t].y)/2; if(a[t].num==k) return ; if(a[t].num!=-1) { a[temp].num=a[t].num; a[temp+1].num=a[t].num; a[t].num=-1; } if(y<=mid) InsertTree(temp,x,y,k); else if(x>mid) InsertTree(temp+1,x,y,k); else { InsertTree(temp,x,mid,k); InsertTree(temp+1,mid+1,y,k); } return ; } void FindTree(int t,int x,int y) { if(a[t].num!=-1) { mark[a[t].num]=1; return ; } int temp=t*2; int mid=(a[t].x+a[t].y)/2; if(y<=mid) FindTree(temp,x,y); else if(x>mid) FindTree(temp+1,x,y); else { FindTree(temp,x,mid); FindTree(temp+1,mid+1,y); } return ; } int main() { int n,m,t; while(scanf("%d%d%d",&n,&t,&m)!=EOF) { CreatTree(1,1,n); char s[5]; int x,y,z; while(m--) { scanf("%s",s); if(s[0]=='C') { scanf("%d%d%d",&x,&y,&z); int temp; if(x>y) { temp=x; x=y; y=temp; } InsertTree(1,x,y,z); } else { scanf("%d%d",&x,&y); int temp; if(x>y) { temp=x; x=y; y=temp; } int i,sum; sum=0; memset(mark,0,sizeof(mark)); FindTree(1,x,y); for(i=1;i<=t;i++) if(mark[i]) sum++; printf("%d\n",sum); } } } return 0; }
相关文章推荐
- poj 2777 Count Color(线段树区间更新)
- poj 2777 Count Color (线段树区间更新)
- poj 2777 , 线段树
- POJ 2777 Count Color 线段树染色问题+位运算表示状态
- POJ 2777 Count Color (线段树区间更新)
- POJ 2777 Count Color【线段树】
- POJ:2777-Count Color(线段树+状压)
- poj 2777 -- Count Color ( 线段树 )
- poj 2777 线段树难题
- POJ 2777 Count Color(线段树之成段更新)
- POJ 2777 Count Color(线段树:区间覆盖)
- POJ Count Color 2777(线段树)
- poj 2777 Count Color 线段树区间更新
- POJ 2777 Count Color (线段树)
- POJ 2777 Count Color(线段树区间修改+位运算)
- POJ 2777 Count Color ---线段树
- poj 2777 Count Color(线段树区间修改)
- POJ 2777 线段树
- POJ 2777 Count Color(线段树+位运算)
- poj_2777_线段树