概述
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4325
大意:本题就是求在某个时间点上开花的朵数
思路:此题后台测试数据很水,题目给的范围很大,但测试数据并没有他给的这么多,区间处理,树状数组,离散化都能解
1.离散化思想:https://blog.csdn.net/xiangaccepted/article/details/73276826
2.线段树思想:https://www.cnblogs.com/wuwangchuxin0924/p/5971849.html
3.树状数组思想(线段树的一种):https://www.cnblogs.com/wuwangchuxin0924/p/5921130.html
树状数组:
思路:假设更新区间(a,b),从a到b每一个点都要加上一朵,基于树状数组特殊结构,这里是假设从a点开始更新,树状数组会从a点一直加到n点,所以区间更新(a,b)区间只更新a点不用一个一个点去加,为了不影响后面的点的更新要减去多余增加的点update(b+1,-1);然后求sum(x);
1.树状数组
#include<cstdio>
#include<cstring>
#define len 100005
using namespace std;
int n,c[len],ans[len];
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int p)//单点更新
{
for(int i=x;i<=len;i=i+lowbit(i)) c[i]+=p;
}
int sum(int x)//起点到x点的和
{
int t=0;
for(int i=x;i>0;i=i-lowbit(i)) t+=c[i];
return t;
}
int main()
{
int t,m,q,count=0;
scanf("%d",&t);
while(t--)
{
int a,b;
memset(c,0,sizeof(c));
memset(ans,0,sizeof(0));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a,&b);
update(a,1);
update(b+1,-1);
}
for(int i=0;i<m;i++)
{
scanf("%d",&q);
ans[i]=sum(q);
}
printf("Case #%d:n",++count);
for(int i=0;i<m;i++) printf("%dn",ans[i]);
}
return 0;
}
2.树状数组+离散化1
#include<cstdio>
#include<cstring>
#include<algorithm>
#define len 100005
using namespace std;
int n,c[len],ans[len],v[len];
struct node
{
int x,y;
}s[len];
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int p)
{
for(int i=x;i<=len;i=i+lowbit(i)) c[i]+=p;
}
int sum(int x)
{
int t=0;
for(int i=x;i>0;i=i-lowbit(i)) t+=c[i];
return t;
}
int main()
{
int t,m,q,count=0;
scanf("%d",&t);
while(t--)
{
int k=0,h[len];
memset(c,0,sizeof(c));
memset(h,0,sizeof(0));
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%d%d",&s[i].x,&s[i].y);
v[k++]=s[i].x;
v[k++]=s[i].y;
}
for(int i=0;i<m;i++) scanf("%d",&h[i]),v[k++]=h[i];
sort(v,v+k);
int p=unique(v,v+k)-v;
for(int i=0;i<n;i++)
{
int x=lower_bound(v,v+p,s[i].x)-v+1;
int y=lower_bound(v,v+p,s[i].y)-v+1;
update(x,1);
update(y+1,-1);
}
printf("Case #%d:n",++count);
for(int i=0;i<m;i++)
{
int j=lower_bound(v,v+p,h[i])-v+1;
printf("%dn",sum(j));
}
}
return 0;
}
2.树状数组+离散化2
#include<cstdio>
#include<cstring>
#include<algorithm>
#define len 100005
using namespace std;
int n,c[len],ank[len*2];
struct node
{
int i,x;
bool operator <(const node &other)const
{
return x<other.x;
}
}s[len];
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int p)
{
for(int i=x;i<=len;i=i+lowbit(i)) c[i]+=p;
}
int sum(int x)
{
int t=0;
for(int i=x;i>0;i=i-lowbit(i)) t+=c[i];
return t;
}
int main()
{
int t,m,count=0;
scanf("%d",&t);
while(t--)
{
memset(c,0,sizeof(c));
memset(ank,0,sizeof(ank));
scanf("%d%d",&n,&m);
n=n*2;
int h=m+n;
for(int i=0;i<h;i++)
{
scanf("%d",&s[i].x);
s[i].i=i;
}
sort(s,s+h);
int k=1;
ank[s[0].i]=k;
for(int i=1;i<h;i++)
{
if(s[i].x==s[i-1].x) ank[s[i].i]=k;
else ank[s[i].i]=++k;
}
for(int i=0;i<n-1;i+=2)
{
update(ank[i],1);
update(ank[i+1]+1,-1);
}
printf("Case #%d:n",++count);
for(int i=n;i<h;i++) printf("%dn",sum(ank[i]));
}
return 0;
}
3.线段树
#include<cstdio>
#include<algorithm>
#include<cstring>
#define len 100005
using namespace std;
struct node
{
int l,r,sum;
}s[len*4];
struct test
{
int a,b;
}t[len];
int m,n,ans[len];
void pushup(int i)
{
if(s[i].l==s[i].r) return ;
if(s[i].sum)
{
s[i*2].sum+=s[i].sum;
s[i*2+1].sum+=s[i].sum;
s[i].sum=0;
}
}
void build(int l,int r,int i)
{
s[i].l=l;
s[i].r=r;
s[i].sum=0;
if(s[i].l==s[i].r) return ;
int mid=(s[i].l+s[i].r)/2;
build(l,mid,i*2);
build(mid+1,r,i*2+1);
}
void update(int l,int r,int i)
{
if(s[i].l==l&&s[i].r==r)
{
s[i].sum++;
return ;
}
int mid=(s[i].l+s[i].r)/2;
if(mid>=r) update(l,r,i*2);
else if(mid<l) update(l,r,i*2+1);
else
{
update(l,mid,i*2);
update(mid+1,r,i*2+1);
}
}
void query(int i)
{
pushup(i);
if(s[i].l==s[i].r)
{
ans[s[i].l]=s[i].sum;
return ;
}
query(i*2);
query(i*2+1);
}
int main()
{
int count=0,p,h;
scanf("%d",&h);
while(h--)
{
int Max=-1;
memset(ans,0,sizeof(ans));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&t[i].a,&t[i].b);
Max=max(max(t[i].a,t[i].b),Max);
}
build(1,Max,1);
for(int i=1;i<=n;i++) update(t[i].a,t[i].b,1);
query(1);
printf("Case #%d:n",++count);
for(int i=0;i<m;i++)
{
scanf("%d",&p);
printf("%dn",ans[p]);
}
}
return 0;
}
4.线段树+离散化
#include<cstdio>
#include<algorithm>
#include<cstring>
#define len 100005
using namespace std;
struct node
{
int l,r,sum;
}s[len*4];
struct test
{
int x,i;
bool operator <(const test &other)const
{
return x<other.x;
}
}t[len];
int m,n,k,ans[len],v[len];
void pushup(int i)
{
if(s[i].l==s[i].r) return ;
if(s[i].sum)
{
s[i*2].sum+=s[i].sum;
s[i*2+1].sum+=s[i].sum;
s[i].sum=0;
}
}
void build(int l,int r,int i)
{
s[i].l=l;
s[i].r=r;
s[i].sum=0;
if(s[i].l==s[i].r) return ;
int mid=(s[i].l+s[i].r)/2;
build(l,mid,i*2);
build(mid+1,r,i*2+1);
}
void update(int l,int r,int i)
{
if(s[i].l==l&&s[i].r==r)
{
s[i].sum++;
return ;
}
int mid=(s[i].l+s[i].r)/2;
if(mid>=r) update(l,r,i*2);
else if(mid<l) update(l,r,i*2+1);
else
{
update(l,mid,i*2);
update(mid+1,r,i*2+1);
}
}
void query(int i)
{
pushup(i);
if(s[i].l==s[i].r)
{
ans[s[i].l]=s[i].sum;
return ;
}
query(i*2);
query(i*2+1);
}
int main()
{
int count=0,h;
scanf("%d",&h);
while(h--)
{
int Max=-1;
memset(ans,0,sizeof(ans));
scanf("%d%d",&n,&m);
n=n*2;
m+=n;
for(int i=0;i<m;i++)
{
scanf("%d",&t[i].x);
t[i].i=i;
Max=max(t[i].x,Max);
}
build(1,Max,1);
sort(t,t+m);
k=1;
v[t[0].i]=k;
for(int i=1;i<m;i++)
{
if(t[i].x==t[i-1].x) v[t[i].i]=k;
else v[t[i].i]=++k;
}
for(int i=0;i<n-1;i+=2) update(v[i],v[i+1],1);
query(1);
printf("Case #%d:n",++count);
for(int i=n;i<m;i++) printf("%dn",ans[v[i]]);
}
return 0;
}
最后
以上就是诚心香水为你收集整理的hdu4325树状数组,线段树,离散化的全部内容,希望文章能够帮你解决hdu4325树状数组,线段树,离散化所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复