# [BZOJ 1135][POI2009]Lyz

## 题意

$$m$$ 次操作，每次包含两个数 $$r_i,x_i$$ 代表来了 $$x_i$$$$r_i$$ 号脚的人。$$x_i$$ 为负，则代表走了这么多人。 对于每次操作，输出溜冰鞋是否足够。足够输出 TAK, 否则输出 NIE.

$$n\le 2\times 10^5,m\le5\times 10^5,k\le1\times 10^9,d\in[0,n],1\le r_i\le n-d,|x_i|\le1\times 10^9$$

## 题解

$\sum_{i=l}^rs_i>k(r-l+d+1)$

\begin{aligned} \sum_{i=l}^rs_i-k(r-l+1)&>kd \\ \sum_{i=1}^r(s_i-k)&>kd \end{aligned}

$\sum_{i=l}^rs_i>k(n-l+1)$

$\sum_{i=l}^ns_i>k(n-l+1)$

$$S$$$$\langle s_i\rangle$$ 的前缀和, 那么我们可以发现上式等价于:

\begin{aligned} S_n-S_{l-1}&>kn-k(l-1) \\ k(l-1)-S_{l-1}&>kn-S_n \end{aligned}

### 参考代码

#include <bits/stdc++.h>

const int MAXN=1e5+10;
typedef long long intEx;

struct Node{
struct Data{
intEx sum;
intEx lmax;
intEx maxs;
intEx rmax;
Data(){}
Data(intEx val){
this->sum=val;
this->lmax=this->rmax=this->maxs=std::max(this->sum,0ll);
}
Data friend operator+(const Data& a,const Data& b){
Data ans;
ans.sum=a.sum+b.sum;
ans.lmax=std::max(a.lmax,a.sum+b.lmax);
ans.rmax=std::max(a.rmax+b.sum,b.rmax);
ans.maxs=std::max(a.rmax+b.lmax,std::max(a.maxs,b.maxs));
return ans;
}
};
int l;
int r;
Data val;
Node* lch;
Node* rch;
Node(int,int);
void Maintain();
};

int n;
int q;
int k;
int d;

int main(){
scanf("%d%d%d%d",&n,&q,&k,&d);
Node* N=new Node(1,n);
for(int i=0;i<q;i++){
int p,x;
scanf("%d%d",&p,&x);
if(N->val.maxs>1ll*k*d)
puts("NIE");
else
puts("TAK");
}
return 0;
}

Node::Node(int l,int r):l(l),r(r){
if(l==r)
this->val=Data(-k);
else{
int mid=(l+r)>>1;
this->lch=new Node(l,mid);
this->rch=new Node(mid+1,r);
this->Maintain();
}
}

if(this->l==this->r)
this->val=Data(this->val.sum+d);
else{
if(x<=this->lch->r)
else
this->Maintain();
}
}

inline void Node::Maintain(){
this->val=this->lch->val+this->rch->val;
}



#include <bits/stdc++.h>

const int MAXN=1e5+10;
typedef long long intEx;

struct Node{
struct Data{
intEx sum;
intEx lmax;
intEx maxs;
intEx rmax;
Data(){}
Data(intEx val){
this->sum=val;
this->lmax=this->rmax=this->maxs=std::max(this->sum,0ll);
}
Data friend operator+(const Data& a,const Data& b){
Data ans;
ans.sum=a.sum+b.sum;
ans.lmax=std::max(a.lmax,a.sum+b.lmax);
ans.rmax=std::max(a.rmax+b.sum,b.rmax);
ans.maxs=std::max(a.rmax+b.lmax,std::max(a.maxs,b.maxs));
return ans;
}
};
int l;
int r;
Data val;
Node* lch;
Node* rch;
Node(int,int);
void Maintain();
};

struct NodeX{
int l;
int r;
intEx max;
NodeX* lch;
NodeX* rch;
NodeX(int,int);
void PushDown();
void Maintain();
};

int n;
int q;
int k;
int d;

int main(){
scanf("%d%d%d%d",&n,&q,&k,&d);
Node* N=new Node(1,n);
NodeX* K=new NodeX(0,n-1);
for(int i=0;i<q;i++){
int p,x;
scanf("%d%d",&p,&x);
if(p!=n)
//		printf("%lld %lld\n",N->val.maxs,K->max);
if(N->val.maxs>1ll*k*d||K->max>-N->val.sum)
puts("No");
else
puts("Yes");
}
return 0;
}

if(l==r)
this->max=1ll*l*k;
else{
int mid=(l+r)>>1;
this->lch=new NodeX(l,mid);
this->rch=new NodeX(mid+1,r);
this->Maintain();
}
}

this->max+=d;
}

if(l<=this->l&&this->r<=r)
else{
this->PushDown();
if(l<=this->lch->r)
if(this->rch->l<=r)
this->Maintain();
}
}

void NodeX::PushDown(){
}
}

void NodeX::Maintain(){
this->max=std::max(this->lch->max,this->rch->max);
}

Node::Node(int l,int r):l(l),r(r){
if(l==r)
this->val=Data(-k);
else{
int mid=(l+r)>>1;
this->lch=new Node(l,mid);
this->rch=new Node(mid+1,r);
this->Maintain();
}
}

if(this->l==this->r)
this->val=Data(this->val.sum+d);
else{
if(x<=this->lch->r)