分治求平面最近点对,与模板不同的地方在于点分两类,求第一类点中与第二类点中距离最近的点对。计算时如果点为同一类,距离设置为INF即可
//#define LOCAL
#include
using namespace std;
#define DBG printf("%d %s\n",__LINE__,__FUNCTION__)
#define CLOSE ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define mem(t, v) memset ((t) , v, sizeof(t))
#define abs(x) ((x) >= 0 ? (x) : -(x))
#define LF putchar('\n')
#define SP putchar(' ')
#define eb emplace_back
#define mk make_pair
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define eps 1e-6
#define ri register int
#define rl register long long
#define LL long long
#define ULL unsigned long long
template<typename T>
void read(T &x) {x = 0;char ch = getchar();LL f = 1;while(!isdigit(ch)){if(ch == '-')f *= -1;ch = getchar();}while(isdigit(ch)){x = x * 10 + ch - 48; ch = getchar();}x *= f;}
template<typename T, typename... Args>
void read(T &first, Args& ... args) {read(first);read(args...);}
template<typename T>
void write(T arg) {T x = arg;if(x < 0) {putchar('-'); x =- x;}if(x > 9) {write(x / 10);}putchar(x % 10 + '0');}
template<typename T, typename ... Ts>
void write(T arg, Ts ... args) {write(arg);if(sizeof...(args) != 0) {putchar(' ');write(args ...);}}
const LL MOD = 1e9 + 7;
const int MAXN = 2e5 + 50;
const double inf = 1e11;
int T, n;
struct node {
double x, y;
int type;
bool operator < (const node &a) const {
return x < a.x;
}
}po[MAXN], tmp[MAXN];
double dis(node a, node b) {
if(a.type == b.type) {
return inf;
} else {
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
}
double divt(int l, int r) {
if(l >= r) {
return inf;
}
int mid = (l + r) >> 1;
double mid_x = po[mid].x;
double res = min(divt(l, mid), divt(mid + 1, r));
{
int i = l, j = mid + 1, k = 0;
while(i <= mid && j <= r) {
if(po[i].y < po[j].y) {
tmp[k++] = po[i++];
} else {
tmp[k++] = po[j++];
}
}
while(i <= mid) {
tmp[k++] = po[i++];
}
while(j <= r) {
tmp[k++] = po[j++];
}
for(i = 0, j = l; i < k; ++i, ++j) {
po[j] = tmp[i];
}
}
int k = 0;
for(ri i = l; i <= r; ++i) {
if(po[i].x >= mid_x - res && po[i].x <= mid_x + res) {
tmp[k++] = po[i];
}
}
for(ri i = 0; i < k; ++i) {
for(ri j = i - 1; j >= 0 && tmp[i].y - tmp[j].y < res; --j) {
res = min(res, dis(tmp[i], tmp[j]));
}
}
//printf("%.3lf\n", res);
return res;
}
int main() {
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
read(T);
while(T--) {
read(n);
for(ri i = 0; i < n; ++i) {
scanf("%lf %lf", &po[i].x, &po[i].y);
po[i].type = 0;
}
for(ri i = n; i < 2 * n; ++i) {
scanf("%lf %lf", &po[i].x, &po[i].y);
po[i].type = 1;
}
sort(po, po + 2 * n);
printf("%.3lf\n", divt(0, 2 * n - 1));
}
return 0;
}
二分答案,单调性在于偶数+奇数为奇数,偶数+偶数为偶数。因为只存在一个奇数点,所以对整条线段做前缀和,奇数点及后面的前缀和为奇数,前面的为偶数。
//#define LOCAL
#include
using namespace std;
#define DBG printf("%d %s\n",__LINE__,__FUNCTION__)
#define CLOSE ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define mem(t, v) memset ((t) , v, sizeof(t))
#define abs(x) ((x) >= 0 ? (x) : -(x))
#define LF putchar('\n')
#define SP putchar(' ')
#define eb emplace_back
#define mk make_pair
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define eps 1e-6
#define ri register int
#define rl register long long
#define LL long long
#define ULL unsigned long long
template<typename T>
void read(T &x) {x = 0;char ch = getchar();LL f = 1;while(!isdigit(ch)){if(ch == '-')f *= -1;ch = getchar();}while(isdigit(ch)){x = x * 10 + ch - 48; ch = getchar();}x *= f;}
template<typename T, typename... Args>
void read(T &first, Args& ... args) {read(first);read(args...);}
template<typename T>
void write(T arg) {T x = arg;if(x < 0) {putchar('-'); x =- x;}if(x > 9) {write(x / 10);}putchar(x % 10 + '0');}
template<typename T, typename ... Ts>
void write(T arg, Ts ... args) {write(arg);if(sizeof...(args) != 0) {putchar(' ');write(args ...);}}
const LL MOD = 1e9 + 7;
const int MAXN = 2e5 + 50;
struct node {
LL s, e, d;
}p[MAXN];
int T, n;
int getsum(LL k) {
int res = 0;
for(ri i = 1; i <= n; ++i) {
if(k >= p[i].s) {
if(k > p[i].e) {
res += (p[i].e -p[i].s) / p[i].d + 1;
} else {
res += (k - p[i].s) / p[i].d + 1;
}
}
}
return res;
}
bool check(LL k) {
if(getsum(k) % 2) {
return true;
} else {
return false;
}
}
int main() {
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
read(T);
while(T--) {
read(n);
for(ri i = 1; i <= n; ++i) {
read(p[i].s, p[i].e, p[i].d);
}
LL l = 0, r = 1e10;
if(getsum(r) % 2 == 0) {
printf("There's no weakness.\n");
continue;
}
while(l < r) {
LL mid = (l + r) >> 1;
if(check(mid)) {
r = mid;
} else {
l = mid + 1;
}
}
int ans = 0;
for(ri i = 1; i <= n; ++i) {
if(r <= p[i].e && r >= p[i].s) {
ans += (r - p[i].s) % p[i].d == 0 ? 1 : 0;
}
}
write(r, ans), LF;
}
return 0;
}
临项交换证明的贪心,类似于国王游戏
//#define LOCAL
#include
using namespace std;
#define DBG printf("%d %s\n",__LINE__,__FUNCTION__)
#define CLOSE ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define mem(t, v) memset ((t) , v, sizeof(t))
#define abs(x) ((x) >= 0 ? (x) : -(x))
#define LF putchar('\n')
#define SP putchar(' ')
#define eb emplace_back
#define mk make_pair
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define eps 1e-6
#define ri register int
#define rl register long long
#define LL long long
#define ULL unsigned long long
template<typename T>
void read(T &x) {x = 0;char ch = getchar();LL f = 1;while(!isdigit(ch)){if(ch == '-')f *= -1;ch = getchar();}while(isdigit(ch)){x = x * 10 + ch - 48; ch = getchar();}x *= f;}
template<typename T, typename... Args>
void read(T &first, Args& ... args) {read(first);read(args...);}
template<typename T>
void write(T arg) {T x = arg;if(x < 0) {putchar('-'); x =- x;}if(x > 9) {write(x / 10);}putchar(x % 10 + '0');}
template<typename T, typename ... Ts>
void write(T arg, Ts ... args) {write(arg);if(sizeof...(args) != 0) {putchar(' ');write(args ...);}}
const LL MOD = 1e9 + 7;
const int MAXN = 5e4 + 50;
struct node {
LL w, s;
bool operator < (const node &a) const {
return w + s < a.w + a.s;
}
}p[MAXN];
LL n;
int main() {
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
read(n);
for(ri i = 1; i <= n; ++i) {
read(p[i].w, p[i].s);
}
sort(p + 1, p + n + 1);
LL now = 0, ans = -1e18;
for(ri i = 1; i <= n; ++i) {
//write(p[i].w, p[i].s), LF;
ans = max(ans , now - p[i].s);
now += p[i].w;
}
write(ans), LF;
return 0;
}
贪心,策略为以 x x x从大到小的顺序考虑每一个任务,如果能匹配机器,则从能匹配的机器中选择机器 y y y最小的一个。贪心的证明思路类似于0x00贪心专题中防晒一题。寻找 y y y的时候用multiset以保证时间复杂度
//#define LOCAL
#include
using namespace std;
#define DBG printf("%d %s\n",__LINE__,__FUNCTION__)
#define CLOSE ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define mem(t, v) memset ((t) , v, sizeof(t))
#define abs(x) ((x) >= 0 ? (x) : -(x))
#define LF putchar('\n')
#define SP putchar(' ')
#define eb emplace_back
#define mk make_pair
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define eps 1e-6
#define ri register int
#define rl register long long
#define LL long long
#define ULL unsigned long long
template<typename T>
void read(T &x) {x = 0;char ch = getchar();LL f = 1;while(!isdigit(ch)){if(ch == '-')f *= -1;ch = getchar();}while(isdigit(ch)){x = x * 10 + ch - 48; ch = getchar();}x *= f;}
template<typename T, typename... Args>
void read(T &first, Args& ... args) {read(first);read(args...);}
template<typename T>
void write(T arg) {T x = arg;if(x < 0) {putchar('-'); x =- x;}if(x > 9) {write(x / 10);}putchar(x % 10 + '0');}
template<typename T, typename ... Ts>
void write(T arg, Ts ... args) {write(arg);if(sizeof...(args) != 0) {putchar(' ');write(args ...);}}
const LL MOD = 1e9 + 7;
const int MAXN = 1e5 + 50;
struct node {
int x, y;
bool operator < (const node &a) const {
if(x == a.x) {
return y < a.y;
}
return x < a.x;
}
}p[MAXN], q[MAXN];
int n, m;
int main() {
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
while(cin >> n >> m) {
for(ri i = 1; i <= n; ++i) {
read(p[i].x, p[i].y);
}
for(ri i = 1; i <= m; ++i) {
read(q[i].x, q[i].y);
}
sort(p + 1, p + n + 1);
sort(q + 1, q + m + 1);
LL ans = 0, cnt = 0;
multiset<int>se;
for(ri i = m, j = n; i >= 1; --i) {
while(j >= 1 && p[j].x >= q[i].x) {
se.insert(p[j].y), --j;
}
auto it = se.lower_bound(q[i].y);
if(it != se.end()) {
++cnt;
ans += 500 * q[i].x + 2 * q[i].y;
se.erase(it);
}
}
cout << cnt << ' ' << ans << endl;
}
return 0;
}