kop采矿
采矿(KOP)
金矿的老师傅年底要退休了。经理为了奖赏他的尽职尽责的工作,决定送他一块长方形地。长度为S,宽度为W。老师傅可以自己选择这块地。显然其中包含的采金点越多越好。你的任务就是计算最多能得到多少个采金点。如果一个采金点的位置在长方形的边上,它也应当被计算在内。
任务:
读入采金点的位置。计算最大的价值。
输入:
文件KOP.IN的第一行是S和W,(1<=s,w<=10 000);他们分别平行于OX坐标和OY坐标,指明了地域的尺寸。接下来一行是整数n (1<=n<=15 000),表示采金点的总数。然后是n行,每行两个整数,给出了一个采金点的坐标。坐标范围是(-30 000<=x,y<=30 000)。
输出:
一个整数,最多的采金点数。
样例输入
1 2
12
0 0
1 1
2 2
3 3
4 5
5 5
4 2
1 4
0 5
5 0
2 3
3 2
样例输出
4
做法:
建立一颗平衡树,从左到右扫描
#include<iostream> #include<cstdlib> #include<algorithm> #include<cstdio> #include<fstream> #include<string> #include<cstring> using namespace std; const int maxn=30010; struct oo{ int v,sum,maxsum; }; struct o{ int x,y; }; oo a[maxn*4]; o b[15010]; int n,m,s,w,num(0),ans(0); inline void init(){ memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); scanf("%d%d",&s,&w); scanf("%d",&n); for (int i=0; i<n; ++i){ scanf("%d%d",&b[i].x,&b[i].y); b[i].x+=30000; b[i].y+=30000; } } inline bool cmp(const o c, const o d){ return c.x<d.x; } inline int max(const int x, const int y){ return x>y?x:y; } inline void build(int k){ if (2*k<=60001) build(2*k); a[k].v=num++; if (2*k+1<=60001) build(2*k+1); } inline void insert_t(const int y, const int delta){ int k=1; while (a[k].v!=y){ if (y<a[k].v) k<<=1; else k=(k<<1)+1; } while (k>0){ a[k].sum+=delta; if ((k<<1)+1<60001){ a[k].maxsum=max(a[k<<1].maxsum,a[k].sum-a[(k<<1)+1].sum); a[k].maxsum=max(a[k].maxsum,a[k].sum-a[(k<<1)+1].sum+a[(k<<1)+1].maxsum); k>>=1; continue; } if ((k<<1)<60001){ a[k].sum=max(a[k<<1].maxsum,a[k].sum); k>>=1; continue; } a[k].maxsum=a[k].sum; k>>=1; } } inline void solve(){ build(1); sort(b,b+n,cmp); int l=0, r=0; insert_t(b[0].y,1); if (b[0].y+w+1<60001) insert_t(b[0].y+w+1,-1); while (true){ while (r<n-1&&b[r+1].x-b[l].x<=s){ ++r; insert_t(b[r].y,1); if (b[r].y+w+1<60001) insert_t(b[r].y+w+1,-1); } if (a[1].maxsum>ans) ans=a[1].maxsum; int t=b[l].x; while (l<=n-1&&b[l].x==t){ insert_t(b[l].y,-1); if (b[l].y+w+1<60001) insert_t(b[l].y+w+1,1); ++l; } if (r>=n-1||l>=n-1) break; } printf("%d\n",ans); } int main(){ freopen("kop.in","r",stdin); freopen("kop.out","w",stdout); init(); solve(); fclose(stdin); fclose(stdout); return 0; }