啊啊啊,刚学线段树,用线段树写这题不断的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;
}