zoukankan      html  css  js  c++  java
  • hdu 2777(线段树)

    这道题是看了别人的思路才做出来的。

    刚看完这道题没什么思路,线段的长度是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
    ",sum);
    			}
    		}
    	}
    	return 0;
    }


  • 相关阅读:
    Vue的配置安装与项目创建
    log4j:WARN No appenders could be found for logger
    终于在博客园扎根了
    简单工厂模式
    详解apache防盗链网站图片防盗链方法
    怎样能写好文章标题
    生活需要阿Q精神
    2013个人博客全新起航
    华中师范大学新生网上怎么选宿舍
    华中师范大学2012级新生QQ交流群欢迎加入!
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3206607.html
Copyright © 2011-2022 走看看