hdu 5124(区间更新+单点求值+离散化)
lines
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1575 Accepted Submission(s): 656
Problem Description
John
has several lines. The lines are covered on the X axis. Let A is a
point which is covered by the most lines. John wants to know how many
lines cover A.
Input
The first line contains a single integer T(the data for N less than 11 cases),indicating the number of test cases.
Each test case begins with an integer N,indicating the number of lines.
Next N lines contains two integers X and Y,describing a line.
Each test case begins with an integer N,indicating the number of lines.
Next N lines contains two integers X and Y,describing a line.
Output
For each case, output an integer means how many lines cover A.
Sample Input
2
5
1 2
2 2
2 4
3 4
5 1000
5
1 1
2 2
3 3
4 4
5 5
Sample Output
3
1
Source
题意:一些线段互相覆盖,求这个线段上面的覆盖线段数最多的点被多少线段覆盖??
题解:看到线段就想到区间更新,然后看到点就想到单点求值,然后只有100000个线段,但是范围却有 1 - 10^9 所以离散化一下。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include <queue> using namespace std; const int N = 100005; int a[N],b[N],x[2*N]; int c[2*N]; int n; int MAX ; int lowbit(int x){ return x&-x; } void update(int idx,int v){ for(int i=idx;i<=2*n;i+=lowbit(i)){ c[i] +=v; } } int getsum(int idx){ int sum = 0; for(int i=idx;i>=1;i-=lowbit(i)){ sum+=c[i]; } return sum; } int main() { int tcase; scanf("%d",&tcase); while(tcase--){ memset(c,0,sizeof(c)); scanf("%d",&n); int cnt = 1; for(int i=1;i<=n;i++){ scanf("%d%d",&a[i],&b[i]); x[cnt++] = a[i]; x[cnt++] = b[i]; } int k = 2; sort(x+1,x+cnt); for(int i=2;i<cnt;i++){ if(x[i]==x[i-1]) continue; x[k++] = x[i]; } for(int i=1;i<=n;i++){ int l = lower_bound(x+1,x+k,a[i])-(x); int r = lower_bound(x+1,x+k,b[i])-(x); update(l,1); update(r+1,-1); } int MAX = -1; for(int i=1;i<=2*n;i++){ MAX = max(MAX,getsum(i)); } printf("%d\n",MAX); } return 0; }