• BZOJ1135:[POI2009]Lyz(线段树,Hall定理)


    Description

    初始时滑冰俱乐部有1到n号的溜冰鞋各k双。已知x号脚的人可以穿x到x+d的溜冰鞋。 有m次操作,每次包含两个数ri,xi代表来了xi个ri号脚的人。xi为负,则代表走了这么多人。 对于每次操作,输出溜冰鞋是否足够。

    Input

    n m k d ( 1≤n≤200,000 , 1≤m≤500,000 , 1≤k≤10^9 , 0≤d≤n ) ri xi ( 1≤i≤m, 1≤ri≤n-d , |xi|≤10^9 )

    Output

    对于每个操作,输出一行,TAK表示够 NIE表示不够。

    Sample Input

    4 4 2 1
    1 3
    2 3
    3 3
    2 -1

    Sample Output

    TAK
    TAK
    NIE
    TAK

    Solution

    这还是第一次听说$Hall$定理……

    $Hall$定理:设一个二分图左边有$n$个点,右边有$m$个点,则左边$n$个点能完全匹配的充要条件是:对于$1<=i<=n$,左面任意$i$个点,都至少有$i$个右面的点与它相连。

    那么考虑把鞋码相同的人放到一起,设鞋码为$i$的有$a[i]$个人。

    贪心的想这个题,肯定是选二分图左边一段连续区间才更容易匹配无解。

    所以由$Hall$定理得,不合法的话是存在一组$l,r$,满足

    $sum_{i=l}^{r} a[i]>(r-l+1+d)*k$。

    把右边的$(r-l+1)*k$移到左边,并且设$c[i]=a[i]-k$,则有

    $sum_{i=l}^{r} c[i]>d*k$。

    由于$d*k$是定值,所以我们只需要用一个维护最大子段和的线段树就可以判断是否合法了。

    Code

     1 #include<iostream>
     2 #include<cstdio>
     3 #define N (200009)
     4 #define LL long long
     5 using namespace std;
     6 
     7 struct Sgt{LL lmax,rmax,max,val;}Segt[N<<2];
     8 LL n,m,k,d,r,x,a[N];
     9 
    10 void Pushup(LL now)
    11 {
    12     LL ls=now<<1,rs=now<<1|1;
    13     Segt[now].val=Segt[ls].val+Segt[rs].val;
    14     Segt[now].lmax=max(Segt[ls].lmax,Segt[ls].val+Segt[rs].lmax);
    15     Segt[now].rmax=max(Segt[rs].rmax,Segt[rs].val+Segt[ls].rmax);
    16     Segt[now].max=max(max(Segt[ls].max,Segt[rs].max),Segt[ls].rmax+Segt[rs].lmax);
    17 }
    18 
    19 void Update(LL now,LL l,LL r,LL x,LL v)
    20 {
    21     if (l==r)
    22     {
    23         Segt[now].val+=v; Segt[now].max+=v;
    24         Segt[now].lmax+=v; Segt[now].rmax+=v;
    25         return;
    26     }
    27     LL mid=(l+r)>>1;
    28     if (x<=mid) Update(now<<1,l,mid,x,v);
    29     else Update(now<<1|1,mid+1,r,x,v);
    30     Pushup(now);
    31 }
    32 
    33 int main()
    34 {
    35     scanf("%lld%lld%lld%lld",&n,&m,&k,&d);;
    36     for (int i=1; i<=n; ++i) Update(1,1,n,i,-k);
    37     for (int i=1; i<=m; ++i)
    38     {
    39         scanf("%lld%lld",&r,&x);
    40         Update(1,1,n,r,x);
    41         puts(Segt[1].max>k*d?"NIE":"TAK");
    42     }
    43 }
  • 相关阅读:
    Debian如何永久添加静态路由
    一句话换个说法的软件
    高级程序员简历,技术总监喜欢什么简历?
    CP936实际上是GBK,编码问题再次让我熬夜
    句子说法转换的软件,基于AI技术
    输入关键词自动生成文章(2020年人工智能写作)
    自动写文章的智能软件(基于AI写作)
    python调用接口,python接收post请求接口(附完整代码)
    人工智能是铁饭碗还是铁坑,看看人工智能博士怎么说
    远离外包公司,就是远离码农的血汗工厂
  • 原文地址:https://www.cnblogs.com/refun/p/10055314.html
Copyright © 2020-2023  润新知