HDU-4325-Flowers
成段更新加离散化线段树
这题做了快有一天了。。。。各种问题啊,开始建树时没有把查询的节点加入树中,结果在查询时发现很多节点的信息丢失了,纠结了半天去看了下别人的代码,原来建树时就应把查询的节点加入,在做离散化时,将hash数组开到10^9,又超内存了,通不过编译,囧,之后改成map映射,终于羞愧的A了(这题的数据可能比较弱,不加离散化也能过)
[cpp]
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
#define N 100005
map<int,int>h;
int x[3*N]; //要加上查询的节点
int ask[N];
struct cam2
{
int x;
int y;
}flower[N*2];
struct cam1
{
int x;
int y;
int sum;
int add;
}list[N*4];
void build(int k,int x,int y)
{
int mid;
list[k].add=0;
list[k].x=x;
list[k].y=y;
list[k].sum=0;
if(list[k].x==list[k].y)
return;
mid=(x+y)/2;
build(k<<1,x,mid);
build(k<<1|1,mid+1,y);
}
void update(int k,int x,int y,int d)
{
int mid;
if(list[k].x==x&&list[k].y==y)
{
list[k].sum+=(list[k].y-list[k].x+1)*d;
list[k].add+=d;
return;
}
if(list[k].add!=0)
{
list[k<<1].sum+=(list[k<<1].y-list[k<<1].x+1)*list[k].add;
list[k<<1|1].sum+=(list[k<<1|1].y-list[k<<1|1].x+1)*list[k].add;
list[k<<1].add+=list[k].add;
list[k<<1|1].add+=list[k].add;
list[k].add=0;
}
mid=(list[k].x+list[k].y)/2;
if(x>mid)
update(k<<1|1,x,y,d);
else if(y<=mid)
update(k<<1,x,y,d);
else
{
update(k<<1,x,mid,d);
update(k<<1|1,mid+1,y,d);
}
list[k].sum=list[k<<1].sum+list[k<<1|1].sum;
}
int find(int k,int x,int y)
{
int mid;
if(list[k].x==x&&list[k].y==y)
return list[k].sum;
if(list[k].add!=0)
{
list[k<<1].sum+=(list[k<<1].y-list[k<<1].x+1)*list[k].add;
list[k<<1|1].sum+=(list[k<<1|1].y-list[k<<1|1].x+1)*list[k].add;
list[k<<1].add+=list[k].add;
list[k<<1|1].add+=list[k].add;
list[k].add=0;
}
mid=(list[k].x+list[k].y)/2;
if(x>mid)
return find(k<<1|1,x,y);
else if(y<=mid)
return find(k<<1,x,y);
return find(k<<1,x,mid)+find(k<<1|1,mid+1,y);
}
int main()
{
int k,t,n,m,i,cnt,num;
scanf("%d",&t);
for(k=1;k<=t;k++)
{
scanf("%d%d",&n,&m);
cnt=0;
for(i=0;i<n;i++)
{
scanf("%d%d",&flower[i].x,&flower[i].y);
x[cnt++]=flower[i].x;
x[cnt++]=flower[i].y;
}
printf("Case #%d:\n",k);
for(i=0;i<m;i++) //建树时就将要查询的节点插入,否则在查询时会丢失节点信息
{
scanf("%d",&ask[i]);
x[cnt++]=ask[i];
}
sort(x,x+cnt);
cnt=unique(x,x+cnt)-x;
h.clear();
for(i=0;i<cnt;i++) //减小建树的空间
h[x[i]]=i;
build(1,0,cnt-1);
for(i=n-1;i>=0;i--)
update(1,h[flower[i].x],h[flower[i].y],1);
for(i=0;i<m;i++) www.zzzyk.com
printf("%d\n",find(1,h[ask[i]],h[ask[i]]));
}
return 0;
}
作者:Cambridgeacm
补充:软件开发 , C++ ,