zoukankan      html  css  js  c++  java
  • 【BZOJ1135】[POI2009]Lyz 线段树

    【BZOJ1135】[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

    题解:如果出现不够用的情况,那么一定是存在连续的一些人,他们把能穿的鞋子都穿完了还是不够,即存在l<r,且$(r-l+d+1)*k le sum[l..r] $。

    移项,得$sum[l..r]-(r-l+1)*k ge d*k $,有没有看出什么?我们将所有数的权值-k,那么就变成了整个区间的最大连续子段和>=d*k。用线段树维护即可。

     

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #define lson x<<1
    #define rson x<<1|1
    using namespace std;
    typedef long long ll;
    int n,m;
    ll K,D;
    const int maxn=200010;
    struct node
    {
    	ll s,lm,rm,sm;
    	node() {s=lm=rm=sm=0;}
    	node(ll a) {s=a,lm=rm=sm=max(a,0ll);}
    	node operator + (const node &b)	const
    	{
    		node c;
    		c.s=s+b.s;
    		c.lm=max(lm,s+b.lm);
    		c.rm=max(b.rm,rm+b.s);
    		c.sm=max(rm+b.lm,max(sm,b.sm));
    		return c;
    	}
    }s[maxn<<2];
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')	f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+(gc^'0'),gc=getchar();
    	return ret*f;
    }
    void build(int l,int r,int x)
    {
    	if(l==r)
    	{
    		s[x]=node(-K);
    		return ;
    	}
    	int mid=(l+r)>>1;
    	build(l,mid,lson),build(mid+1,r,rson);
    	s[x]=s[lson]+s[rson];
    }
    void updata(int l,int r,int x,int a,ll b)
    {
    	if(l==r)
    	{
    		s[x]=node(s[x].s+b);
    		return ;
    	}
    	int mid=(l+r)>>1;
    	if(a<=mid)	updata(l,mid,lson,a,b);
    	else	updata(mid+1,r,rson,a,b);
    	s[x]=s[lson]+s[rson];
    }
    int main()
    {
    	n=rd(),m=rd(),K=rd(),D=rd();
    	int i,a,b;
    	build(1,n,1);
    	for(i=1;i<=m;i++)
    	{
    		a=rd(),b=rd(),updata(1,n,1,a,b);
    		if(s[1].sm>K*D)	printf("NIE
    ");
    		else	printf("TAK
    ");
    	}
    	return 0;
    }//4 4 2 1 1 3 2 3 3 3 2 -1 

     

  • 相关阅读:
    改 hadoop ssh 端口
    java.lang.OutOfMemoryError: Java heap space 解决方法
    LucidGaze for Solr 搜索监测工具
    hadoop 文件浏览器
    CF1427C Solution
    技术经理必备的六个好习惯
    今天申请博客
    同志们都走了!!
    好笑
    今天看了《浅谈多态》这篇文章
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7787706.html
Copyright © 2011-2022 走看看