线段树【p2801】教主的魔法

Description

教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1、2、……、N。

每个人的身高一开始都是不超过1000的正整数。教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内的英雄的身高全部加上一个整数W。(虽然L=R时并不符合区间的书写规范,但我们可以认为是单独增加第L(R)个英雄的身高)

CYZ、光哥和ZJQ等人不信教主的邪,于是他们有时候会问WD闭区间 [L, R] 内有多少英雄身高大于等于C,以验证教主的魔法是否真的有效。

WD巨懒,于是他把这个回答的任务交给了你。

Input

第1行为两个整数N、Q。Q为问题数与教主的施法数总和。

第2行有N个正整数,第i个数代表第i个英雄的身高。

第3到第Q+2行每行有一个操作:

(1) 若第一个字母为“M”,则紧接着有三个数字L、R、W。表示对闭区间 [L, R] 内所有英雄的身高加上W。

(2) 若第一个字母为“A”,则紧接着有三个数字L、R、C。询问闭区间 [L, R] 内有多少英雄的身高大于等于C。

Output

对每个“A”询问输出一行,仅含一个整数,表示闭区间 [L, R] 内身高大于等于C的英雄数。

线段树做的,不过貌似正解是分块.(不会分块啊 emm

差点被输入搞疯的一个题,输入竟然有好多个空格 qwq.难受得一逼.

结果发现是自己查询操作忘了判边界

维护区间最小值,维护\(tag\)标记.

暴力去找某个区间最小值\(\geq C\),直接累计答案.

不要忘记下放\(tag\)和判断\(l==r\)

代码

#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#define R register
#define ls o<<1
#define rs o<<1|1
#define N 1000008
using namespace std;
inline void in(int &x)
{
	int f=1;x=0;char s=getchar();
	while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
	while(isdigit(s)){x=x*10+s-'0';s=getchar();}
	x*=f;
}
int n,m,tg[N<<3],mnn[N<<3];
inline void up(int o)
{
	mnn[o]=min(mnn[ls],mnn[rs]);
	return;
}
inline void down(int o)
{
	if(tg[o])
	{
		tg[ls]+=tg[o];tg[rs]+=tg[o];
		mnn[ls]+=tg[o];mnn[rs]+=tg[o];
		tg[o]=0;
	}
	return;
}
void build(int o,int l,int r)
{
	if(l==r)
	{
		in(mnn[o]);
		return;
	}
	int mid=(l+r)>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	up(o);
}
void change(int o,int l,int r,int x,int y,int del)
{
	if(x<=l and y>=r)
	{
		tg[o]+=del;mnn[o]+=del;
		return;
	}
	down(o);
	int mid=(l+r)>>1;
	if(x<=mid) change(ls,l,mid,x,y,del);
	if(y>mid) change(rs,mid+1,r,x,y,del);
	up(o);
}
int query(int o,int l,int r,int x,int y,int k)
{
	if(mnn[o]>=k and x<=l and y>=r)
		return(r-l+1);;
	if(l==r)return 0;
	down(o);
	int mid=(l+r)>>1,res=0;
	if(x<=mid) res+=query(ls,l,mid,x,y,k);
	if(y>mid) res+=query(rs,mid+1,r,x,y,k);
	return res;
}
int main()
{
	in(n),in(m);
	build(1,1,n);
	for(R int l,r,z;m;m--)
	{
		R char opt[6];
		scanf("%s%d%d%d",opt,&l,&r,&z);
		if(opt[0]=='A')
			printf("%d\n",query(1,1,n,l,r,z));
		else change(1,1,n,l,r,z);
	}
}
posted @ 2018-10-14 20:56  顾z  阅读(269)  评论(1编辑  收藏  举报