• [POI2009]Lyz


    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

    终于从网络流中解放出来了。

    这题怎么说呢,还是和二分图有点关系。根据霍尔定理,我们可以得出如果在某一个时刻不符合要求的话,那么对于一个l,r,一定有((r-l+1+d)*k<sum_{lle i le r}a_i)随便移项就可以得出(sum_{lle i le r}a_i-(r-l+1) imes k>d*k)然后在建树的时候把所有点-k就可以用线段树维护了。

    所以说这题叫动态最大子段和??

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    #include <string>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <set>
    #include <map>
    #define re register
    #define MAXN 200005
    #define ls (rt<<1)
    #define rs (rt<<1|1)
    #define mid (l+r>>1)
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    #define ms(arr) memset(arr, 0, sizeof(arr))
    #define int ll
    const int inf = 0x3f3f3f3f;
    int maxl[MAXN<<2],maxr[MAXN<<2],sum[MAXN<<2],maxx[MAXN<<2];
    int n,m,K,d;
    inline void pushup(int rt)
    {
    	sum[rt]=sum[ls]+sum[rs];
    	maxl[rt]=max(maxl[ls],sum[ls]+maxl[rs]);
    	maxr[rt]=max(maxr[rs],sum[rs]+maxr[ls]);
    	maxx[rt]=max(maxx[ls],max(maxx[rs],maxl[rs]+maxr[ls]));
    }
    inline void build(int l,int r,int rt)
    {
    	if(l==r){
    		maxx[rt]=-K;sum[rt]=-K;
    		return;
    	}
    	build(l,mid,ls);build(mid+1,r,rs);
    	pushup(rt);
    }
    inline void update(int x,int y,int l,int r,int rt)
    {
    	if(l==r) {
    		maxx[rt]+=y;sum[rt]+=y;
    		maxl[rt]=maxr[rt]=max(sum[rt],0ll);
    		return;
    	}
    	if(mid>=x) update(x,y,l,mid,ls);
    	else update(x,y,mid+1,r,rs);
    	pushup(rt);
    }
    inline int read()
    {
        int x=0,c=1;
        char ch=' ';
        while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();
        while(ch=='-') c*=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar();
        return x*c;
    }
    main() 
    {
        n=read();m=read();K=read();d=read();
        build(1,n,1);
        for(re int i=1;i<=m;i++){
        	int x=read(),y=read();
        	update(x,y,1,n,1);
        	if(maxx[1]<=K*d) printf("TAK
    ");
        	else printf("NIE
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    LeetCode 977 有序数组的平方
    LeetCode 24 两两交换链表中的节点
    LeetCode 416 分割等和子集
    LeetCode 142 环形链表II
    LeetCode 106 从中序与后序遍历序列构造二叉树
    LeetCode 637 二叉树的层平均值
    LeetCode 117 填充每个节点的下一个右侧节点
    LeetCode 75 颜色分类
    redhat 7.4 挂载ntfs格式的u盘并且使用
    redhat 查看CPU frequency scaling(CPU频率缩放)
  • 原文地址:https://www.cnblogs.com/victorique/p/9139512.html
Copyright © 2020-2023  润新知