zoukankan      html  css  js  c++  java
  • $bzoj1135$

    $Hall定理+线段树$

    $Hall定理:对于有完美匹配的二分图,从全部匹配的那一侧选择k个元素,另一侧至少有k个元素与其相连,这里指的是元素的并集,这个是充要条件,也就是我们可以用这个条件判断二分图是否有完美匹配,这里就用到了。完美匹配就是指全部匹配了$

    $题目里人和鞋构成二分图,要求人有完美匹配,那么我们运用Hall定理,只要任意选出k个人相邻的鞋至少有k双就行了,但是如果直接枚举的话复杂度是指数级的$

    $观察一下发现,事实上如果任意连续的一段人满足了,那么不连续的肯定满足,因为每个人对应的鞋是[x,x+k],那么对于一段连续的人我们挖掉中间的一个人不会让对应的鞋的集合变小,所以我们只用看连续的人就可以了,用线段树检查,但是复杂度是O(n^{2}logn)的$

    $继续观察,事实上可以化简成这样的一个式子sum_{i=l}^{r}{a[i]}leq{(r-l+k+1)*d}$

    $然后就很简单了,相当于sum_{i=l}^{r}{a[i]-k}leq{k*d}$

    $由于k*d是定值,那么我们用线段树维护左边的式子,查询最大子段和就行了$

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 2e5 + 5;
    int n, m, k, d;
    ll l[N << 2], r[N << 2], sum[N << 2], mx[N << 2];
    void update(int L, int R, int x, int p, int d) {
        if(L == R) {
            mx[x] += d;
            sum[x] += d;
            l[x] += d;
            r[x] += d;
            return;
        }
        int mid = (L + R) >> 1;
        if(p <= mid) {
            update(L, mid, x << 1, p, d);
        } else {
            update(mid + 1, R, x << 1 | 1, p, d);
        }
        sum[x] = sum[x << 1] + sum[x << 1 | 1];
        l[x] = max(l[x << 1], sum[x << 1] + l[x << 1 | 1]);
        r[x] = max(r[x << 1 | 1], sum[x << 1 | 1] + r[x << 1]);
        mx[x] = max(mx[x << 1], max(mx[x << 1 | 1], r[x << 1] + l[x << 1 | 1]));
    }
    void build(int L, int R, int x) {
        if(L == R) {
            mx[x] = l[x] = r[x] = sum[x] = -k;
            return;
        }
        int mid = (L + R) >> 1;
        build(L, mid, x << 1);
        build(mid + 1, R, x << 1 | 1);
        sum[x] = sum[x << 1] + sum[x << 1 | 1];
        l[x] = max(l[x << 1], sum[x << 1] + l[x << 1 | 1]);
        r[x] = max(r[x << 1 | 1], sum[x << 1 | 1] + r[x << 1]);
        mx[x] = max(mx[x << 1], max(mx[x << 1 | 1], r[x << 1] + l[x << 1 | 1]));
    }
    int main() {
        scanf("%d%d%d%d", &n, &m, &k, &d);
        build(1, n, 1);
        while(m--) {
            int r, x;
            scanf("%d%d", &r, &x);
            update(1, n, 1, r, x);
            puts(mx[1] <= (ll)d * k ? "TAK" : "NIE");
        }
        return 0;
    } 
    View Code
  • 相关阅读:
    网络多线程 ---实现网络负载图片
    optimizer for eclipse--Eclipse优化,让你的Eclipse快来飞!
    ORACLE AUTOMATIC STORAGE MANAGEMENT翻译-第二章 ASM instance(1)
    IOS 开展 分别制定了iphone 和 ipad 好? 或开发一个 Universal好?
    DevExpress VCL 2014.1.2 for C++BUILDER XE6
    swift http请求返回json数据和分析
    Spark里面的任务调度:离SparkContext开始
    ftk学习记录(一个进度条文章)
    Appium Android Bootstrap控制源代码的分析AndroidElement
    别忽视了业绩比较基准
  • 原文地址:https://www.cnblogs.com/19992147orz/p/8367204.html
Copyright © 2011-2022 走看看