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
  • 相关阅读:
    如何设置ASP.NET页面的运行超时时间
    日志文件清理工具V1.1
    【原创】日志文件清理工具V1.0
    【分享】国外后台界面HTML源码 [免费]
    【分享】仿东软OA协同办公服务管理源码
    年底发福利了——分享一下我的.NET软件开发资源
    由12306动态验证码想到的ASP.NET实现动态GIF验证码(附源码)
    【分享】元旦送礼,商业源码免费赠送!
    给大家分享一个jQuery TAB插件演示
    【分享】双12了,也没啥可送大家的,就送大家点商业源码吧!
  • 原文地址:https://www.cnblogs.com/19992147orz/p/8367204.html
Copyright © 2011-2022 走看看