首页 > 其他分享 >洛谷 P3488 [POI2009]LYZ-Ice Skates 题解

洛谷 P3488 [POI2009]LYZ-Ice Skates 题解

时间:2022-10-10 19:44:40浏览次数:65  
标签:二分 le POI2009 个点 题解 复杂度 Ice 匹配 Hall

错解

每次跑二分图匹配,时间复杂度显然爆炸。

时间复杂度:我被杀手皇后摸过了

正解

引入

Hall 定理:设二分图中 \(G=<V_1,V_2,E>,|V_1| \le |V_2|\),则 G 中 存在 \(V_1\) 到 \(V_2\) 的完美匹配当且仅当 \(\forall S \sub V_1\),均有 \(|S| \le |N(S)|\),其中 \(N(S)=\Cup_{V_i \in S}{N(V_i)}\),是 \(S\) 的邻域。

通俗来说,对于一个二分图,它的左面有 \(n\) 个点,右面有 \(m\) 个点,则左边 \(n\) 个点能完全匹配的充要条件是对于任意在 \([1,n]\) 之间的 \(i\),左面任意 \(i\) 个点,都至少有 \(i\) 个右面的点与它相连。

证明

充分性:假设一个二分图 \(G\) 不存在完美匹配,且满足 Hall 定理,那么如果有一种最大匹配的方案,既然不存在完美匹配,可以找到至少一个未被匹配的点 \(A\)。

因为这个二分图满足 Hall 定理,所以这个点一定连向了至少一个点 \(B\)(有可能存在多个点)。那么这个点 \(B\) 一定在最大匹配中,左边一定有一个点 \(C\) 和它匹配。

\(C\) 做为一个匹配点可能在右边找到 \(D\),就这样一直找下去,由于左部点数是小于等于右部点数,于是最终点落在右部点结束,找到一个增广路,矛盾,假设不成立。

必要性:假设一个二分图 \(\text{G}\) 存在完美匹配,且不满足 Hall 定理。
那么对于某 \(k\) 个点,它们连向的都不足 \(k\) 个点,这些点无法匹配,矛盾,假设不成立。

转化

我们显然不能枚举所有情况,这样的时间复杂度是 \(O(2^p)\) 的,其中 \(p\) 为人数,所以我们只能考虑最劣的情况。

显然,选择连续号码的人会使右边与他相邻的人最少。

设 \([l,r]\) 为脚号码的范围,\(a_i\) 表示型号为 \(i\) 的人数,由 Hall 定理得:

\[\sum^r_{i=l}a_i \le k(r-l+1+d) \qquad (1) \]

如果单纯这样做的话,修改是 \(O(n^2 \log n)\) 的,询问是 \(O(m^2)\) 的,时间复杂度依然接受不了。

考虑将 \((1)\) 式变形,得:

\[\sum^r_{i=l}(a_i-k)\le d \cdot k \qquad (2) \]

\((2)\) 式中由于 \(d \cdot k\) 是个定值,那么问题变为单点修改+求最大连续子序列和,可以用线段树维护(最开始时令 \(a_i=-k\))。

代码

//P3488 [POI2009]LYZ-Ice Skates
#include <iostream>
#include <cstdio>
using namespace std;
#define int long long
const int MAXN=2e5+5;
struct SegmentTree
{
    int lmx,rmx,sum,res;
}tr[MAXN<<2];
int n,m,k,d;
void pushup(int p)
{
    tr[p].lmx=max(tr[p<<1].lmx,tr[p<<1].sum+tr[p<<1|1].lmx);
    tr[p].rmx=max(tr[p<<1|1].rmx,tr[p<<1|1].sum+tr[p<<1].rmx);
    tr[p].sum=tr[p<<1].sum+tr[p<<1|1].sum;
    tr[p].res=max(tr[p<<1].res,max(tr[p<<1|1].res,tr[p<<1].rmx+tr[p<<1|1].lmx));
    return;
}
void build(int p,int l,int r)
{
    int mid;
    if(l==r)
    {
        tr[p]={0,0,-k,-k};
        return;
    }
    mid=(l+r)>>1;
    build(p<<1,l,mid);
    build(p<<1|1,mid+1,r);
    pushup(p);
    return;
}
void update(int p,int l,int r,int k,int c)
{
    int mid;
    if(l==r)
    {
        tr[p].sum+=c;
        tr[p].res+=c;
        tr[p].lmx=tr[p].rmx=max(0ll,tr[p].sum);
        return;
    }
    mid=(l+r)>>1;
    if(k<=mid)
    {
        update(p<<1,l,mid,k,c);
    }
    else 
    {
        update(p<<1|1,mid+1,r,k,c);
    }
    pushup(p);
    return;
}
signed main()
{
    int x,y;
    scanf("%lld%lld%lld%lld",&n,&m,&k,&d);
    build(1,1,n);
    for(int i=1;i<=m;i++)
    {
        scanf("%lld%lld",&x,&y);
        update(1,1,n,x,y);
        if(tr[1].res<=k*d)
        {
            printf("TAK\n");
        }
        else 
        {
            printf("NIE\n");
        }
    }
    return 0;
}
/*
 * 洛谷
 * https://www.luogu.com.cn/problem/P3488
 * C++17 -O0
 * 2022.10.10
 */

标签:二分,le,POI2009,个点,题解,复杂度,Ice,匹配,Hall
From: https://www.cnblogs.com/2020gyk080/p/16776921.html

相关文章

  • 【题解】XXI Opencup GP of Tokyo Count Min Ratio
    有\(R\)个红球,\(B\)个蓝球和一个绿球,同色球之间无区别。将其任意排列,令\(l_R,l_B,r_R,r_B\)分别为绿球左/右边的红/蓝球数量。定义一个方案的权值为\(\max\{x\i......
  • Criss Cross OJ【R001】8月月赛I题解合集
    R0011.「T1」积木高塔Solution返回题目简要题意:给定一个矩阵,以及其每一格中完全相同立方体的高度(即个数),求:这座高塔最高点的高度。这座高塔从第\(1\)层到最高......
  • AtCoder Regular Contest 150 (ARC150) - A+B+C+D 题解
    A题意给定一个由0,1和?组成的长为\(n\)序列,其中?需要被替换为0或1,询问是否有且仅有一种?的替换方案使得序列中有\(k\)个1并且这\(k\)个1是连续的序......
  • js 字符串 截取字串 slice,substring,substr方法对比
    js字符串截取字串slice,substring,substr方法对比1.slice()方法slice()提取字符串的某个部分并在新字符串中返回被提取的部分。该方法设置两个参数:起始索引(开始位......
  • [题解]守护者的挑战
    题目描述打开了黑魔法师Vani的大门,队员们在迷宫般的路上漫无目的地搜寻着关押applepi的监狱的所在地。突然,眼前一道亮光闪过。“我,Nizem,是黑魔法圣殿的守卫者。如果你能通......
  • 生成https license
     方法一:1.key的生成 1openssl genrsa -des3 -out server.key 2048这样是生成rsa私钥,des3算法,openssl格式,2048位强度。server.key是密钥文件......
  • dotnet C# 使用 Vortice 支持 Direct2D1 离屏渲染
    本文告诉大家如何使用Vortice进行D2D的离屏渲染功能,本文将在一个纯控制台无窗口的应用下,使用Direct2D1进行离屏绘制,将绘制结果保存为本地图片文件本文属于使用Vort......
  • Luogu P6880 [JOI 2020 Final] オリンピックバス 题解
    [P6880JOI2020Final]オリンピックバス-洛谷|计算机科学教育新生态(luogu.com.cn)两条前置知识:在图\(G\)上构造根为\(x\)的最短路树\(T\),我们删除任意一条......
  • ARC150 A+C题题解。
    如题,ARC150A题C题的解题报告。#A-Continuous1###题意:有1,0,?组成的一个序列(?可以为0/1),问恰好有且仅有k个i,且连续的情况有多少种。###分析:考虑O(n).常见为转......
  • P6772 [NOI2020] 美食家 题解
    一道不错的题目。一个朴素的dp就是\(f_{i,x}\)表示时间\(i\)时从1走到\(x\)的最大美味值,就有转移\(f_{i,v_j}=\max\{f_{i-w_j,u_j}+c_{v_j}+美食节贡献\}\),结......