CF516E 做题记录
纪念一下独立切的 *3100 的数论 + 贪心题,思考时的思路一波三折,像极了考试中的我。
个人感觉难度至少 *3300。
考虑先求出
因此当
我们考虑求出使得全部女生快乐的最小天数,求男生的天数只需要把两堆人对调。
考虑编号为
那么我们把
钦定环上一个点的 id 为从
把所有快乐的女生编号对应的 id,以及快乐的男生编号
对于每个拎出来的点
时间复杂度
点击查看代码
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define fi first
#define se second
#define pir pair <ll, ll>
#define mkp make_pair
#define pb push_back
using namespace std;
void read(ll &x) {
char c; ll f = 1;
while(!isdigit(c = getchar()))
if(c == '-') f = -1;
x = c - '0';
while(isdigit(c = getchar())) x = x * 10 + c - '0';
x *= f;
}
const ll maxn = 4e5 + 10, inf = 1e17;
ll nl, ml, n, m, g;
vector <ll> v1[maxn], v2[maxn];
ll ans;
void exgcd(ll a, ll b, ll &x, ll &y) {
if(!b) {
x = 1, y = 0;
return;
}
exgcd(b, a%b, x, y);
ll t = x;
x = y, y = t - a / b * y;
}
ll Get(ll i) {
ll x, y;
exgcd(nl, ml, x, y);
x *= i, y *= i;
x = (x % ml + ml) % ml;
return x;
}
ll iGet(ll i) {return i * nl % ml;}
ll h[maxn], ht, mn[maxn], vis[maxn];
void solve(ll u) {
ht = 0;
for(ll i: v1[u]) {
ll x = i / g;
ll id = Get(x % ml);
h[++ht] = id;
}
for(ll i: v2[u]) {
ll x = i / g;
ll id = Get(x);
h[++ht] = id;
}
if(!ht) {ans = inf; return;}
sort(h + 1, h + 1 + ht);
ht = unique(h + 1, h + 1 + ht) - h - 1;
for(ll i = 1; i <= ht; i++)
mn[i] = inf, vis[i] = 0;
for(ll i : v1[u]) {
ll x = i / g;
ll id = Get(x % ml);
ll Id = lower_bound(h + 1, h + 1 + ht, id) - h;
mn[Id] = min(mn[Id], i);
}
for(ll i : v2[u]) {
ll x = i / g;
ll id = Get(x);
ll Id = lower_bound(h + 1, h + 1 + ht, id) - h;
mn[Id] = min(mn[Id], i), vis[Id] = 1;
}
for(ll i = 1; i <= ht; i++) {
ll x = (h[i] + ml - 1) % ml, j = (i + ht - 2) % ht + 1;
if(x == h[j] && vis[j]) continue;
ll ret = mn[j] + (x - h[j] + ml) % ml * nl * g;
ans = max(ans, ret);
}
}
int main() {
read(nl), read(ml), read(n);
g = __gcd(nl, ml);
nl /= g, ml /= g;
if(g > 2e5) {puts("-1"); return 0;}
for(ll i = 1, x; i <= n; i++) {
read(x);
v1[x % g].pb(x);
}
read(m);
for(ll i = 1, x; i <= m; i++) {
read(x);
v2[x % g].pb(x);
}
for(ll i = 0; i < g; i++) {
sort(v1[i].begin(), v1[i].end());
sort(v2[i].begin(), v2[i].end());
}
for(ll i = 0; i < g; i++)
solve(i);
for(ll i = 0; i < g; i++) swap(v1[i], v2[i]);
swap(nl, ml);
for(ll i = 0; i < g; i++)
solve(i);
if(ans == inf) ans = -1;
printf("%lld", ans);
return 0;
}
出处:https://www.cnblogs.com/Sktn0089/p/18182518
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】