zoukankan      html  css  js  c++  java
  • [CF981F]Round Marriage[二分+霍尔定理]

    题意

    洛谷

    分析

    • 参考了Icefox
    • 首先二分,然后考虑霍尔定理判断是否有完美匹配。如果是序列的话,因为这里不会出现 (j<i,L(i)<L(j)) 或者 (j<i,R(i)<R(j)) 的情况,所以可以不用线段树,直接判断是否存在 (j,i(j<i)) 满足 (R(i)-L(j)+1<i-j+1) (只需要判断连续的一段)。
    • 因为是环,考虑将 (a,b) 数列分别倍长,但是发现环上到达某个 (b) 仍然需要讨论。此时只需要在最左边和最右边再加一倍 (b) 序列就可以处理了。
    • 总时间复杂度 (O(nlogn))

    总结这种霍尔定理的套路:

    1. 对于同样的 (digamma) 能够增加 (x) 集合的大小就增加。
    2. (x) 集合可以拆成两个 $digamma $ 不相交的集合时一定分开讨论。
    3. 对于同样种类(大小)的 (x) 集合只讨论最具有影响力的。
    4. "非完美算法" 思想在查找 (digamma(x))(并集) 时的体现。
    5. 讨论二分图的哪一边取决于是否便于操作。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    #define go(u) for(int i = head[u], v = e[i].to; i; i=e[i].lst, v=e[i].to)
    #define rep(i, a, b) for(int i = a; i <= b; ++i)
    #define pb push_back
    #define re(x) memset(x, 0, sizeof x)
    inline int gi() {
        int x = 0,f = 1;
        char ch = getchar();
        while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar();}
        while(isdigit(ch)) { x = (x << 3) + (x << 1) + ch - 48; ch = getchar();}
        return x * f;
    }
    template <typename T> inline void Max(T &a, T b){if(a < b) a = b;}
    template <typename T> inline void Min(T &a, T b){if(a > b) a = b;}
    const int N = 2e5 + 7, inf = 0x3f3f3f3f;
    int n, L;
    LL a[N << 1], b[N << 2];
    bool check(int mid) {
    	int mx = -inf;
    	for(int i = 1, j1 = 1, j2 = 1; i <= 2 * n; ++i) {
    		while(j1 <= 4 * n && b[j1] < a[i] - mid) ++j1;
    		while(j2 <= 4 * n && b[j2] <= a[i] + mid) ++j2;
    		Max(mx, j1 - i);
    		if(j2 - i - 1 < mx) return 0;
    	}
    	return 1;
    }
    int main() {
    	n = gi(), L = gi();
    	rep(i, 1, n) a[i] = gi();
    	sort(a + 1, a + 1 + n);
    	rep(i, 1, n) b[i] = gi();
    	sort(b + 1, b + 1 + n);
    	for(int i = 1; i <= n; ++i) a[i] += L, a[i + n] = a[i] + L;
    	for(int i = 1; i <= 3 * n; ++i) b[i + n] = b[i] + L;
    	int l = 0, r = L / 2;
    	while(l < r) {
    		int mid = l + r >> 1;
    		if(check(mid)) r = mid;
    		else l = mid + 1;
    	}
    	printf("%d
    ", l);
    	return 0;
    }
    
  • 相关阅读:
    OOP侧边分享按钮
    表格基础操作
    行为型模式之自定义语言的实现(解释器模式)
    行为型模式之请求发送者与接收者解耦(命令模式)
    行为型模式之请求的链式处理(职责链模式)
    Http、Socket、WebSocket之间联系与区别
    日期时间工具类DateTimeUtil(基于Java8的LocalDateTime)
    结构型模式之代理模式
    Java8 函数式接口@FunctionalInterface的使用说明
    结构型模式之实现对象的复用(享元模式)
  • 原文地址:https://www.cnblogs.com/yqgAKIOI/p/10224714.html
Copyright © 2011-2022 走看看