挺简单的一道题,我看到n和m都是5000觉得暴力应该是没有问题的,然后就写了个m*n的遍历,T到毫无朋友。。。
后来感觉应该用二分,不过总觉得这道题的二分应该很诡异,自己的姿势不好可能会写崩,再加上看见discuss里面一群人说暴力可过,就无耻的信了。。。
然后就改呗=_=比如说把函数都加inline啊,形参都加const (ElemType)&啊,循环里加个break啊,去掉几个特判啊。。。。。。
然而这并没有用(desu)
所以说最后死心塌地的写二分,居然不用debug一遍就过了!
最后PS:给c++跪了,以下代码交C++CE。。。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <climits>
#include <iostream>
#include <algorithm>
using namespace std;
const double eps = 1e-9;
struct P
{
double x, y;
P() {}
P(double x, double y) : x(x), y(y) {}
double add(double a, double b)
{
if(abs(a + b) < eps * (abs(a) + abs(b))) return 0;
else return a + b;
}
P operator + (const P &q)
{
return P(add(x, q.x), add(y, q.y));
}
P operator - (const P &q)
{
return P(add(x, -q.x), add(y, -q.y));
}
P operator * (const double &b)
{
return P(x * b, y * b);
}
bool operator == (const P &q)
{
return x == q.x && y == q.y;
}
double det(const P &q)
{
return x * q.y - y * q.x;
}
double dot(const P &q)
{
return x * q.x + y * q.y;
}
};
int part[5117];
double part_up[5117], part_down[5117], x1, x2, y1, y2;
P toys[5117];
int n, m;
inline void init()
{
memset(part, 0, sizeof(part));
return ;
}
inline bool on_bound(P p, const P &up1, const P &down2)
{
if(p.x == up1.x)
{
part[0] += 1;
return true;
}
if(p.x == down2.x)
{
part[n] += 1;
return true;
}
return false;
}
inline bool on_part(P p, int pos)
{
P up1(0, y1), up2(0, y1), down1(0, y2), down2(0, y2);
if(pos == 0)
{
up1.x = x1, up2.x = part_up[pos], down1.x = x1, down2.x = part_down[pos];
}
else
{
up1.x = part_up[pos - 1], up2.x = part_up[pos], down1.x = part_down[pos - 1], down2.x = part_down[pos];
}
if((down1 - up1).det(p - up1) * (up2 - down2).det(p - down2) > 0)
{
return true;
}
return false;
}
void bin_search(int l, int r, P p)
{
while(l <= r)
{
int mid = (l + r) / 2;
if((p - P(part_down[mid], y2)).det(P(part_up[mid], y1) - P(part_down[mid], y2)) > 0)
{
if(!on_part(p, mid + 1)) l = mid + 1;
else
{
part[mid + 1] += 1;
return ;
}
}
else if((p - P(part_down[mid], y2)).det(P(part_up[mid], y1) - P(part_down[mid], y2)) < 0)
{
if(!on_part(p, mid)) r = mid - 1;
else
{
part[mid] += 1;
return ;
}
}
}
return ;
}
int main()
{
int i, j, k, cse = 1;
while(scanf("%d", &n) != EOF)
{
if(n == 0) break;
scanf("%d %lf %lf %lf %lf", &m, &x1, &y1, &x2, &y2);
init();
for(i = 0; i < n; ++i)
{
scanf("%lf %lf", &part_up[i], &part_down[i]);
}
part_up[n] = part_down[n] = x2;
P now;
i = 0;
P up1(x1, y1), down2(x2, y2);
while(i < m)
{
scanf("%lf %lf", &now.x, &now.y);
if(on_bound(now, up1, down2))
{
++i;
continue;
}
bin_search(0, n, now);
++i;
}
if(cse != 1) printf("\n");
++cse;
for(i = 0; i <= n; ++i)
{
printf("%d: %d\n", i, part[i]);
}
}
return 0;
}