zoukankan      html  css  js  c++  java
  • 线段树【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
    ",query(1,1,n,l,r,z));
    		else change(1,1,n,l,r,z);
    	}
    }
    
  • 相关阅读:
    2019-9-2-C#枚举中使用Flags特性
    2019-9-2-C#枚举中使用Flags特性
    2019-8-31-C#-转换类型和字符串
    2019-8-31-C#-转换类型和字符串
    2019-8-31-C#-获取进程退出代码
    2019-8-31-C#-获取进程退出代码
    access truncate
    GIT分布式版本控制系统
    iSCSI的配置(target/initiator)
    chkconfig命令
  • 原文地址:https://www.cnblogs.com/-guz/p/9787920.html
Copyright © 2011-2022 走看看