1. 程式人生 > 實用技巧 >一本通1754:棧的維護

一本通1754:棧的維護

連結

十分抽象的一道題(於我而言)。

注意遞迴的式子中的函式可以被常量替換。

#include<bits/stdc++.h>
#define IL inline
#define ls k<<1
#define rs k<<1|1
#define LL long long
using namespace std;
const int N=2e5+3;
int n,q,d[N],v[N];
IL int in(){
	char c;int f=1;
	while((c=getchar())<'0'||c>'9')
	  if(c=='-') f=-1;
	int x=c-'0';
	while((c=getchar())>='0'&&c<='9')
	  x=x*10+c-'0';
	return x*f;
}
struct segment{
	int add[N<<2],del[N<<2],sum[N<<2];
	int query(int k,int cnt){
		if(add[k]<=cnt) return 0;
		if(!cnt) return sum[k];
		if(add[rs]>=cnt) return sum[k]-sum[rs]+query(rs,cnt);
		return query(ls,cnt-add[rs]+del[rs]);
	}
	IL void pushup(int k){
		del[k]=del[ls]+max(0,del[rs]-add[ls]),
		add[k]=add[rs]+max(0,add[ls]-del[rs]),
		sum[k]=sum[rs]+query(ls,del[rs]);
	}
	void build(int k,int l,int r){
		if(l==r){
			if(d[l]) del[k]=v[l];
			else add[k]=1,sum[k]=v[l];
			return;
		}
		int mid=l+r>>1;
		build(ls,l,mid),build(rs,mid+1,r);
		pushup(k);
	}
	void mdy(int k,int l,int r,int u,int d,int v){
		if(l==r){
			if(d) del[k]=v,sum[k]=add[k]=0;
			else add[k]=1,del[k]=0,sum[k]=v;
			return;
		}
		int mid=l+r>>1;
		if(u<=mid) mdy(ls,l,mid,u,d,v);
		else mdy(rs,mid+1,r,u,d,v);
		pushup(k);
	}
}T;
int main()
{
	n=in(),q=in(); 
	for(int i=1;i<=n;++i) d[i]=in(),v[i]=in();
	T.build(1,1,n);
	for(int i=1;i<=q;++i){
		int k=in(),d=in(),v=in();
		T.mdy(1,1,n,k,d,v);
		printf("%d\n",T.sum[1]);
	}
	return 0;
}