【学习笔记】「JOISC 2020 Day1」汉堡肉

该博客探讨了一种数学问题,涉及用最少数量的竹签覆盖二维平面上的正方形。文章介绍了针对不同竹签数量(k≤4)的解题策略,包括鸽巢原理的应用和2-SAT模型的构建。对于k=4的情况,通过建立特定图并进行tarjan算法求解。博主分享了经过调试的代码实现,并提供了可能的输出样例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

solution:

考点:数学 + 2-sat 模型。

观察 k≤4k\leq 4k4 肯定有猫腻。

设所有正方形的右边界最小值为 mnxmnxmnx

则可以证明若有解一定存在一个竹签使得其纵坐标为 mnxmnxmnx ,即调整坐标得到不劣的方案。

类似的也有同样的性质。对于 k≤3k\leq 3k3 的情况,根据鸽巢原理,一定存在一个竹签落在四个角上。直接 O(4kn)O(4^kn)O(4kn) 爆搜即可。

对于 k=4k=4k=4 的情况,正确考虑方式为:如果一个矩形如果和三条直线相交,那么一定包含一条边界,可以不用考虑;否则考虑 2-sat 模型。限制条件为:若两个区间不存在交,则一定不能被同一条边覆盖。

那我们可以把 l, r 端点分别 push_back 进每一个可能满足的边,对于每个 l, 向满足 r<l 的点建边,同理,对于每个 r,向满足 l>r 的点建边。可以 two-pointers 完成。这样要构造 2*3=6 倍节点。

时间复杂度 O(n(logn+4k))O(n(logn+4^k))O(n(logn+4k)) 。代码好恶心。

代码是 zyyzyyzyy 的,做了一些改动。debugdebugdebug 了一晚上终于改对了代码。

#include <bits/stdc++.h>
#define PII pair<int,int>
#define INF 0x3f3f3f3f
#define ll long long
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
using namespace std;
const int mx = 2e5 + 5;
const int mxn = mx * 6;
int n, k, nd, cnt[mx], id[mx][2], pr[mx], su[mx], at[mx][2];
int dfn[mxn], low[mxn], vis[mxn], c[mxn], s[mxn], tp, bl, num;
struct qry {
   
   
    int x, v0, v1;
    bool operator <(const qry &a) const {
   
   
        return x < a.x;
    }
};
vector<qry> vl[4], vr[4];
vector<int> g[mxn];
PII ans[5]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值