poj2352~树状数组~线段树尝试失败~

啊啊啊,刚学线段树,用线段树写这题不断的TLE!我自己弄了15000个数据,秒算的,结果还是说我TLE,搞了2个小时没看出哪里能超时—  —。

然后用之前学的树状。十分钟就搞定了,两种代码都先放这里,线段树那个以后再拿出来看看哪里TLE

/********树状数组解法*************/
#include<iostream>
#include<string>
using namespace std;

int c[35000],Sum[15010];
int  Getsum(int i)    //查询0到i区间的数值状况
{
	int s=0;
	while(i>0)
	{
		s+=c[i];
		i-=i&(-i);
	}
	return s;
}

void update(int i,int value)//更新0到i区间的数值状况
{
	while(i<=35500)
	{
		c[i]+=value;
		i+=i&(-i);
	}
}

int main()
{
	int n,i,j,x,y,s;
	scanf("%d",&n);
	memset(Sum,0,sizeof(Sum));
	for(i=0;i<n;i++)
	{
		scanf("%d%d",&x,&y);
		s=Getsum(x+1); //为了防止0的情况,这里的X统一都加个1
		Sum[s]++;
		update(x+1,1);
	}
	for(i=0;i<n;i++)
		printf("%d\n",Sum[i]);
}

 

下面是错误的线段树解法,因为是第一次写代码很长,如果有兴趣帮我看看哪错我会很感激的~

#include<iostream>
#include<string>
#include<fstream>
using namespace std;

int Sum[16000];

typedef struct STAR
{
    int   left;
     int right;
     int cover;  
    STAR   *leftchild;
    STAR   *rightchild;    
};

STAR * build(int   l ,  int r ) 
{
    STAR *root=new STAR;
	root->cover=0;
    root->left = l;
    root->right = r;     
    root->leftchild = NULL;
    root->rightchild = NULL;

    if ( l +1<= r )
    {
       int  mid = (r+l) /2;
       root->leftchild = build ( l , mid ) ;
       root->rightchild = build ( mid+1  , r) ; 
    } 

    return   root; 
}

void  Insert(int c, int d , STAR  *root )
{     
	if(root==NULL) return ;
	int mid=(root->left+root->right)/2;
	if(c==root->left&&d==root->right) 
		root->cover++;
    else
	{	
		root->cover++;
		if(d<=mid)
			Insert(c,d,root->leftchild);
		else if(c>mid)
			Insert(c,d,root->rightchild);
	}
}

int  Count(STAR *root,int c,int d)
{
    int  mid;
	if(root==NULL) return 0;
	mid=(root->left+root->right)/2;
	if(root->left==c&&root->right==d)
		 return root->cover;
	else
	{
	    if(d<=mid)
			return Count(root->leftchild,c,d);
		 else 
		 {
			return Count(root->leftchild,c,mid)+Count(root->rightchild,mid+1,d);
		 }
	}	
}

int main()
{
	int n,i,j,x,y,s;
	STAR *root;
	scanf("%d",&n);
	root=build(0,32100);
	for(i=0;i<n;i++)
		Sum[i]=0;
	for(i=0;i<n;i++)
	{
		scanf("%d%d",&x,&y);
		s=Count(root,0,x);
		Sum[s]++;
		Insert(x,x,root);
	}
	for(i=0;i<n;i++)
		printf("%d\n",Sum[i]);
	return 0;
}



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值