P3488 [POI2009]LYZ-Ice Skates

Portal

This question is based on bipartite graph matching, and to know that a $ Hall $ theorem: For the necessary and sufficient conditions bipartite graph can exact match is less set points there is left, points to $ n $, for $ k \ in [1, n] $, $ k $ left any point on the right must have at least $ k $ connected to the left point and the points

It seems it is not difficult to prove, first of all the need is obvious

Then consider the set of n-$ $ left for points, if he is satisfied Hall $ $ $ Theorem and there is a point $ X_a not match, then the point is connected to the $ X_a $ $ Y_ {b, c, d ..} $ must have both match at this time was a $ X_ {b, c, d ...} $ matching $ Y_ {b, c, d ...} $,

So obtained from the theorem of $ Hall $ $ X_a, X_ {b, c, d ...} $ set of points constituting the point there is a certain edge connected to $ Y_ {b, c, d} $ outside ( otherwise, the Y $ $ $ X-points less than $ points),

It is possible to go on like this has been augmented eventually will be able to find an augmenting path

Then consider how to ensure the title there must be an exact match, obviously as long as we consider the period of continuous models of people, which would allow the right of the idle position as little as possible

If not legal then there must be a continuous period of $ [l, r] $, such that $ \ sum_ {i = l} ^ {r} X_i> (r-l + 1 + d) * k $, where $ X_i $ is number of people number $ i $ feet, the formula represents more people than shoes

Variable expression that is about $ \ sum_ {i = l} ^ {r} (X_i-k)> d * k $, so long as we can determine whether there is a continuous section of $ $ and Xk is greater than $ d * k $ 

Direct maintenance at the largest sub-segment by segment tree and can

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
const int N=4e5+7;
int n,m,K,D;
struct Segtree {
    ll sum[N<<2],mx[N<<2],lmx[N<<2],rmx[N<<2];
    inline void pushup(int o)
    {
        int lc=o<<1,rc=o<<1|1;
        mx[o]=max( max(mx[lc],mx[rc]) , max(0ll,rmx[lc]+lmx[rc]) );
        lmx[o]=max( max(0ll,lmx[lc]) , sum[lc]+lmx[rc] );
        rmx[o]=max( max(0ll,rmx[rc]) , sum[rc]+rmx[lc] );
        sum[o]=sum[lc]+sum[rc];
    }
    void build(int o,int l,int r)
    {
        if(l==r) { sum[o]=-K; return; }
        int mid=l+r>>1; build(o<<1,l,mid); build(o<<1|1,mid+1,r);
        pushup(o);
    }
    void change(int o,int l,int r,int pos,int v)
    {
        if(l==r) { sum[o]+=v; lmx[o]=rmx[o]=mx[o]=max(0ll,sum[o]); return; }
        int mid=l+r>>1;
        pos<=mid ? change(o<<1,l,mid,pos,v) : change(o<<1|1,mid+1,r,pos,v);
        pushup(o);
    }
    ll query() { return mx[1]; }
}T;
int main()
{
    n=read(),m=read(),K=read(),D=read();
    T.build(1,1,n); int a,b;
    for(int i=1;i<=m;i++)
    {
        a=read(),b=read(); T.change(1,1,n,a,b);
        if(T.query()>1ll*K*D) printf("NIE\n");
        else printf("TAK\n");
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/LLTYYC/p/11574518.html