首页 > 其他分享 >[ARC069F] Flags

[ARC069F] Flags

时间:2024-05-10 15:55:05浏览次数:24  
标签:int res rev ARC069F fx Flags fy find

题意

有 \(n\) 个旗子。

你需要将她们插在数轴上。

第 \(i\) 个旗子只能放在 \(x_i\) 或 \(y_i\) 处。

你需要求所有旗子的最小距离 \(d\) 的最大值。

Sol

二分个答案先。

考虑 \(\text{check}\),注意到这是个 \(\text{2-sat}\) 的经典模型。

具体地,设 \(S = x \cup y\) 若 \(|S_i - S_j| < D\),则连边 \(i \to rev(j)\)。

这里 \(rev(p)\) 表示若 \(p = x_i\) 则 \(rev(p) = y_i\) 反之亦然。

集中注意力,显然这个东西可以表示成一个点向一个区间连边。

直接线段树优化建图,然后跑 \(\text{tarjan}\) 即可。

但是这样代码会很难看,我不喜欢。

考虑更小清新的 \(\text{kosaraju}\)。

注意到实际上我们需要做的事情只有快速知道一个点所贡献的区间有哪些点没被经过。

很显然了吧,在区间上维护一个并查集,\(f_x\) 表示 \(rev(x)\) 是否被经过。

对于反图,注意到实际上走的点依然是一个区间,区别在于正图是 \(u \to rev(v)\),而反图就变成了 \(rev(u) \to v\)。

实现有一定细节。

Code

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <array>
#include <vector>
#define pii pair <int, int>
using namespace std;
#ifdef ONLINE_JUDGE

#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
char buf[1 << 23], *p1 = buf, *p2 = buf, ubuf[1 << 23], *u = ubuf;

#endif
int read() {
    int p = 0, flg = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-') flg = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        p = p * 10 + c - '0';
        c = getchar();
    }
    return p * flg;
}
void write(int x) {
    if (x < 0) {
        x = -x;
        putchar('-');
    }
    if (x > 9) {
        write(x / 10);
    }
    putchar(x % 10 + '0');
}
bool _stmer;

#define fi first
#define se second

const int N = 4e4 + 5;

array <int, N> idx;
array <pii, N> s;

int rev(int x, int n) {
    int res = s[x].se;
    if (res <= n) res += n;
    else res -= n;
    return idx[res];
}

namespace Uni {

array <int, N> fa, siz;

int find(int x) {
    if (x == fa[x]) return x;
    return fa[x] = find(fa[x]);
}

void merge(int x, int y) {
    int fx = find(x),
        fy = find(y);
    if (fx == fy) return;
    /* if (siz[fx] > siz[fy]) swap(fx, fy); */
    fa[fx] = fy, siz[fy] += siz[fx];
}

void init(int n) {
    for (int i = 1; i <= n; i++)
        siz[fa[i] = i] = 1;
}

} //namespace Uni

vector <int> arc;
array <int, N> isl;

int tot;

void dfs1(int x, int k, int n, int m) {
    Uni::merge(rev(x, n), rev(x, n) + 1);
    int res = Uni::find(isl[x]);
    /* cerr << x << endl; */
    while (res <= m && s[res].fi - s[x].fi < k) {
        if (res == x) { res = Uni::find(res + 1); continue; }
        /* cerr << x << " " << rev(res, n) << endl; */
        dfs1(rev(res, n), k, n, m);
        res = Uni::find(res);
    }
    arc.push_back(x);
}

array <int, N> col;
int scc;

void dfs2(int x, int k, int n, int m) {
    x = rev(x, n);
    Uni::merge(rev(x, n), rev(x, n) + 1);
    int res = Uni::find(isl[x]);
    while (res <= m && s[res].fi - s[x].fi < k) {
        if (res == x) { res = Uni::find(res + 1); continue; }
        dfs2(res, k, n, m);
        res = Uni::find(res);
    }
    col[x] = scc;
}

bool kosaraju(int n, int m, int k) {
    int res = 1;
    for (int i = 1; i <= m; i++) {
        while (s[i].fi - s[res].fi >= k && res <= m)
            res++;
        isl[i] = res;
    }
    /* for (int i = 1; i <= m; i++) */
        /* write(isl[i]), putchar(32); */
    /* puts(""); */
    Uni::init(m + 1);
    for (int i = 1; i <= m; i++)
        if (rev(i, n) == Uni::find(rev(i, n))) dfs1(i, k, n, m);
    Uni::init(m + 1);
    reverse(arc.begin(), arc.end());
    scc = 0;
    for (auto p : arc)
        if (p == Uni::find(p)) scc++, dfs2(p, k, n, m);
    /* for (int i = 1; i <= m; i++) */
        /* write(col[i]), putchar(32); */
    /* puts("@"); */
    for (int i = 1; i <= m; i++)
        if (col[i] == col[rev(i, n)])
            return 0;
    return 1;
}

bool _edmer;
int main() {
    cerr << (&_stmer - &_edmer) / 1024.0 / 1024.0 << "MB\n";
    int n = read(), m = 0;
    for (int i = 1; i <= n; i++) {
        int x = read(), y = read();
        m++, s[m] = make_pair(x, i);
        m++, s[m] = make_pair(y, i + n);
    }
    sort(s.begin() + 1, s.begin() + 1 + m);
    for (int i = 1; i <= m; i++) idx[s[i].se] = i;
    /* write(kosaraju(n, m, 5)), puts(""); */
    /* return 0; */
    int l = 0, r = 1e9 + 1, ans = -1;
    while (l <= r) {
        int mid = (l + r) >> 1;
        if (kosaraju(n, m, mid))
            l = mid + 1, ans = mid;
        else r = mid - 1;
    }
    write(ans), puts("");
    return 0;
}

标签:int,res,rev,ARC069F,fx,Flags,fy,find
From: https://www.cnblogs.com/cxqghzj/p/18184551

相关文章

  • dbt flags 变量简单说明
    通过flags可以使用dbtcli的一些参数,比较常用的是对于增量物化处理的场景参考使用{%ifflags.FULL_REFRESH%}droptable...{%else%}--no-op{%endif%}说明支持的参数都在flags中可以看看,一些dbtadapter的实现都会使用到此变量参考......
  • Pygame - Special Flags 文档翻译
    PygameSpecialFlags官方文档链接什么是SpecialFlags?​ SpecialFlags是一种控制如何将一个Surface绘制到另一个Surface的方法。它们可以用来创造视觉效果,如发光粒子,或执行表面掩蔽或操作。它们的使用方法如下:pygame.Surface.blit()pygame.Surface.blits()pygame......
  • Go - go build -ldflags
     #downloaddependenciesandbuildRUNgomoddownloadRUNCGO_ENABLED=0GOOS=$TARGETOSGOARCH=$TARGETARCHgobuild-ldflags="-s-w"-o/go/bin/server zzh@ZZHPC:~/aaa$gobuild-ldflags="-help"./main.go#command-line-arguments......
  • EditorGUI.EnumFlagsField实现多选枚举
    效果枚举publicenumMyFontStyleMask{Bold=1,Italic=1<<1,Outline=1<<2,}标签类usingUnityEngine;publicclassMyEnumMaskAttribute:PropertyAttribute{}Property Drawer#ifUNITY_EDITORusingSystem;usingUnityEd......
  • 使用 Feature Flags 实现数据库灰度迁移的监控与可观测性
    作者:观测云与胡博场景描述很多企业会遇到数据库升级、或数据库迁移的情况,尤其是在自建数据库服务向云数据库服务、自建机房向云机房、旧数据库向新数据库迁移等场景。然而,我们需要在整个移植过程中保证其稳定性、避免数据遗失、服务宕机等情况,最常见的移植方法之一就是数据库双写......
  • 无涯教程-Java 正则 - Pattern int flags()函数
    java.util.regex.Pattern.flags()方法返回此模式的匹配标志。intflags()-声明publicintflags()intflags()-返回值编译此模式时指定的匹配标志。intflags()-示例下面的示例显示java.util.regex.Pattern.flags()方法的用法。packagecom.learnfk;importjava.......
  • 无涯教程-Java 正则 - static Pattern compile(String regex, int flags)函数
    java.util.regex.Pattern.compile(Stringregex,intflags)方法将给定的正则表达式编译为一个模式。staticPatterncompile-声明以下是java.util.regex.Pattern.compile(Stringregex,intflags)方法的声明。publicstaticPatterncompile(Stringregex,intflags)reg......
  • MacOS 中的 chflags 命令
    在macOS中,我们可以使用chflags命令来更改文件或目录的标志(flags),从而控制它们的属性和行为。通过修改这些标志,我们可以隐藏文件、防止其被修改或删除,以及进行其他操作。以下是关于chflags命令的一些基本信息和示例用法。语法chflags命令的基本语法如下:chflags[-R]flags......
  • C# 枚举使用[Flags] 特性形成一个位掩码及判断是否存在某个枚举组合
    在C#中,通过给枚举类型添加 [Flags] 特性,可以指示该枚举类型是用于表示位标志的枚举。使用带有 [Flags] 特性的枚举类型允许将多个枚举值组合在一起,形成一个位掩码,提供了一种更方便和可读性更好的方式来表示多个选项的组合。当给枚举类型添加 [Flags] 特性后,可以使用按位或......
  • crash —— 将flags转换成可读的字符
    将page的flags转换为可读字符串crash>kmem-g01fffe00000a001cFLAGS:1fffe00000a001cPAGE-FLAGBITVALUEPG_referenced20000004PG_uptodate30000008PG_dirty40000010PG_reclaim170020000PG_unevictable19......