hdoj 5124 lines【线段树+离散化】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5124
题意:给你n段区间,他们有重合的点A,问你重合最多次的点A重合多少次
题解:对区间离散化后,维护区间最大值
#include<stdio.h> #include<string.h> #include<algorithm> #define LL long long #define MAX 100100 using namespace std; int s[MAX],e[MAX],q[MAX]; int rec[MAX];//记录所有值排序后的下标 int add[MAX<<2]; int sum[MAX<<2]; int le[MAX],ri[MAX]; void pushup(int o) { sum[o]=max(sum[o<<1],sum[o<<1|1]); } void pushdown(int o,int m) { if(add[o]) { add[o<<1]+=add[o]; add[o<<1|1]+=add[o]; sum[o<<1]+=add[o]; sum[o<<1|1]+=add[o]; add[o]=0; } } void gettree(int o,int l,int r) { add[o]=0; if(l==r) { sum[o]=0; return ; } int mid=(l+r)>>1; gettree(o<<1,l,mid); gettree(o<<1|1,mid+1,r); pushup(o); } void update(int o,int l,int r,int L,int R,int val) { if(L<=l&&R>=r) { add[o]+=val; sum[o]+=val; return ; } pushdown(o,r-l+1); int mid=(l+r)>>1; if(L<=mid) update(o<<1,l,mid,L,R,val); if(R>mid) update(o<<1|1,mid+1,r,L,R,val); pushup(o); } int query(int l,int r,int pos)//查找输入当前值,在树中对应的位置 { while(r>=l) { int mid=(l+r)>>1; if(rec[mid]==pos) return mid; else if(rec[mid]>pos) r=mid-1; else l=mid+1; } return -1; } int main() { int t,n,m,k,i; scanf("%d",&t); while(t--) { scanf("%d",&n); int p=1; for(i=0;i<n;i++) { scanf("%d%d",&s[i],&e[i]); rec[p++]=s[i]; rec[p++]=e[i]; } for(i=0;i<m;i++) { scanf("%d",&q[i]); rec[p++]=q[i]; } sort(rec+1,rec+p);// int R=2; for(i=2;i<p;i++)//去除数组中重复的点 { if(rec[i]!=rec[i-1]) rec[R++]=rec[i]; } sort(rec+1,rec+R); gettree(1,1,R-1);//对下标建树 for(int i=0;i<n;i++) { int x=query(1,R-1,s[i]); int y=query(1,R-1,e[i]); update(1,1,R-1,x,y,1); } printf("%d\n",sum[1]); } }