HDU 5124 lines
上周六多校的第一题,给你n条线段(点也算线段),让你找出被覆盖次数最多的线段的覆盖次数。
两种方法。
1,起点终点排序后,依次便利。遇见起点sum++,遇见终点sum--.中间过程的最大值就是最后的结果。
2,线段树+离散化。 第一次接触到离散化这个概念,百科上这样说的:把无限空间中无限的个体映射到有限的空间中去。
这里用map来记录输入的值。
方法一:排序;
/方法一:排序 #include<bits/stdc++.h> using namespace std; int a[100010],b[100010]; int t,n; bool cmp(int aa,int bb) { return aa<bb; } int main() { scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=0; i<n; i++) scanf("%d%d",&a[i],&b[i]); sort(a,a+n,cmp); sort(b,b+n,cmp); int maxx=0,sum=0; int j=0,i=0; while(i!=n && j!=n) { if(b[j]<a[i]) { sum--; j++; } else { sum++; i++; } maxx=max(maxx,sum); //printf("%d\n",maxx); } printf("%d\n",maxx); } return 0; }
方法二:线段树+离散化
//方法二:线段树+;离散化 #include<bits/stdc++.h> using namespace std; #define maxx 100010 int sum; int tree[4*maxx],ss[4*maxx]; void inint(int l,int r,int ll,int rr,int mark) { if(l>rr || r<ll) return ; else if(l<=ll && r>=rr) tree[mark]+=1; else { inint(l,r,ll,(rr+ll)/2,2*mark); inint(l,r,(rr+ll)/2+1,rr,2*mark+1); } } void lazzy(int l,int r,int mark) { if(l==r) { sum=max(sum,tree[mark]); } else { tree[2*mark]+=tree[mark]; tree[2*mark+1]+=tree[mark]; lazzy(l,(l+r)/2,mark*2); lazzy((l+r)/2+1,r,mark*2+1); } } int main() { int t,n; scanf("%d",&t); while(t--) { int k=0,a,b; map<int,int> mapp; fill(tree,tree+maxx*4,0); sum=-1; scanf("%d",&n); for(int i=0; i<n; i++) { scanf("%d%d",&a,&b); ss[k++]=a; ss[k++]=b; } sort(ss,ss+k); int j=1; //离散化 for(int i=0; i<k; i++) { if(!mapp[ss[i]]) { mapp[ss[i]]=j; j++; } } for(int i=0; i<n; i++) { int x=mapp[a[i].x]; int y=mapp[a[i].y]; inint(x,y,1,j-1,1); } lazzy(1,j-1,1); printf("%d\n",sum); } return 0; }