Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1733 Accepted Submission(s): 858
题意:给出N种花的开花时间,求出某一个时间点,得出开花数目
思路:线段树+离散化,比赛时把代码写搓了半天弄不对, 主要是离散化离散的不好(PS:这也是我这个篇报告的原因) 原来我只是对所给的开花时间离散而已,并未对查询的时间也加到一块离散,弄得updata 和 query 操作过于麻烦 只要把要查询的时间也一块离散就方便多了 而且不易错。
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; #define L(rt) (rt<<1) #define R(rt) (rt<<1|1) const int N=100010; struct node{ int l,r,sum; //sum 记录该区间被覆盖的次数 int rl,rr; //rl,rr是原来的区间长度 }tree[N*3]; struct data{ int u,v; }seg[N]; int tim[N<<1],Q[N]; void build(int l,int r,int rt){ tree[rt].l=l; tree[rt].r=r; tree[rt].rl=tim[tree[rt].l]; tree[rt].rr=tim[tree[rt].r]; tree[rt].sum=0; if(l==r) return ; int mid=(l+r)>>1; build(l,mid,L(rt)); build(mid+1,r,R(rt)); } void PushDown(int rt){ //这是延迟操作 tree[L(rt)].sum+=tree[rt].sum; tree[R(rt)].sum+=tree[rt].sum; tree[rt].sum=0; } void update(int l,int r,int rt){ if(l==tree[rt].rl && r==tree[rt].rr){ tree[rt].sum+=1; return ; } if(tree[rt].sum!=0 && tree[rt].l!=tree[rt].r) PushDown(rt); int mid=(tree[rt].l+tree[rt].r)>>1; if(r<=tim[mid]) update(l,r,L(rt)); else if(l>=tim[mid+1]) update(l,r,R(rt)); else{ update(l,tim[mid],L(rt)); update(tim[mid+1],r,R(rt)); } } int query(int num,int rt){ if(tree[rt].sum!=0 && tree[rt].l!=tree[rt].r) PushDown(rt); if(tree[rt].l==tree[rt].r) return tree[rt].sum; int mid=tree[L(rt)].rr; if(num<=mid) return query(num,L(rt)); else return query(num,R(rt)); } int main(){ //freopen("input.txt","r",stdin); int t,n,m; int cases=0; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); tim[0]=-1; //把tim初始为-1只是为了后面排序方便一些而已,也可不初始 int cnt=1,u,v; for(int i=0;i<n;i++){ scanf("%d%d",&u,&v); seg[i].u=u; seg[i].v=v; tim[cnt++]=u; tim[cnt++]=v; } int p; for(int i=0;i<m;i++){ scanf("%d",&p); Q[i]=p; tim[cnt++]=p; } sort(tim,tim+cnt); //离散化 int len=unique(tim,tim+cnt)-(tim+1); build(1,len,1); for(int i=0;i<n;i++) update(seg[i].u,seg[i].v,1); printf("Case #%d:\n",++cases); for(int i=0;i<m;i++){ int ans=query(Q[i],1); printf("%d\n",ans); } } return 0; }