1008 How Many 线段树延迟标记。

http://acm.hrbeu.edu.cn/index.php?act=problem&id=1008&cid=115

线段树,标记。

How Many

TimeLimit: 10 Second   MemoryLimit: 32 Megabyte

Totalsubmit: 188   Accepted: 35  

Description

you are given a sequence A[1], A[2],..., A[N]. On this sequence you have to apply M operations: Add all the elements whose position are in range [l, r] with d or. Ask for a query , thar for position [L,R] ,how many element whose value are in range [l, r].

Input

There're no more than 101 tests and only one big test case, Process until the end of the file. The first line of each case contains two numbers, N, M, described as above. And then start from the second line, have N numbers described the sequence's initial value.

( 1≤ N ≤ 250,000 ; M ≤ 50,000 ; |A[i]| ≤ 1,000,000,000 )

The following M lines described the operation:

C L R d: Add all the element whose positions are in range [L, R] with d.

( 1 <= L <= R <= n ; |d| <= 1,000,000,000 )

Q L R l r: ask for a query, for position [L,R] . There're how many elements, whose value are in range [l, r].

( l ≤ r ; |l|,|r| ≤ 1,000,000,000 ; 1 <= L <= R <= n )

We guarantee every elements are suits 32-integer, and will not cause overflow, even during the running-time. (.. but still be careful :) Besides, all the test-data are generated randomly.

Output

For each query, print the result.

Sample Input

9 4
1 2 3 4 5 6 7 8 9
Q 1 9 1 9
C 1 4 10
C 6 9 -10
Q 1 9 1 9

Sample Output

9
1

Source

ACM/ICPC中国·哈尔滨工程大学第八届程序设计竞赛

 

//题意简单,略。

经典例题。

#include<stdio.h>
#define HH 1
struct st //使用了__int64错误,服务器关系。
{
        long long l;
        long long r;
        long long color;
        long long num;
        long long  max;
        long long  min;
}f[250003*4];
long long  date[250003];
long long  max(long long  x,long long  y)
{
        return x>y? x:y;
}
long long  min(long long  x,long long  y)
{
        return x<y? x:y;
}
void build(long long  l,long long  r,long long  n)
{
        long long  mid=(l+r)/2;
        f[n].l=l;
        f[n].r=r;
        f[n].color=0;
        f[n].num=0;
        if(l==r)
        {
                f[n].max=date[l];
                f[n].min=date[l];
                return ;
        }
        build(l,mid,n*2);
        build(mid+1,r,n*2+1);
        f[n].max=max(f[n*2].max,f[n*2+1].max);
        f[n].min=min(f[n*2].min,f[n*2+1].min);
}
void down(long long  n)
{
        if(f[n*2].color==HH)
                f[n*2].num+=f[n].num;
        else f[n*2].num=f[n].num;

        if(f[n*2+1].color==HH)
                f[n*2+1].num+=f[n].num;
         else f[n*2+1].num=f[n].num;

        f[n*2].max+=f[n].num;
        f[n*2+1].max+=f[n].num;
        f[n*2].min+=f[n].num;
        f[n*2+1].min+=f[n].num;

        f[n].num=0;
        f[n].color=0;
        f[n*2].color=HH;
        f[n*2+1].color=HH;
}

void up(long long  n)
{
        f[n].max=max(f[n*2].max,f[n*2+1].max);
        f[n].min=min(f[n*2].min,f[n*2+1].min);
}
void update(long long  l,long long  r,long long  num,long long  n)
{
        long long  mid=(f[n].l+f[n].r)/2;
        if(f[n].l==l&&f[n].r==r)
        {
                if(f[n].color==HH)
                        f[n].num+=num;
                else f[n].num=num;
                f[n].color=HH;
                f[n].max+=num;
                f[n].min+=num;
                return ;
        }
        if(f[n].color==HH)
                down(n);
        if(mid>=r)
                update(l,r,num,n*2);
                else if(mid<l)
                        update(l,r,num,n*2+1);
        else 
                {
                update(l,mid,num,n*2);
                    update(mid+1,r,num,n*2+1);
                }
                up(n);
        
}
long long query(long long  l,long long  r,long long  numl,long long  numr,long long  n)
{
        long long  mid=(f[n].l+f[n].r)/2;
        long long cos=0;
        if(f[n].l==l&&f[n].r==r)
        {
                if(numl<=f[n].min&&numr>=f[n].max)
                        return f[n].r-f[n].l+1;
                if(f[n].min>numr)return 0;
                else if(f[n].max<numl) return 0;
        }
        if(f[n].l==f[n].r) return 0;     
        if(f[n].color==HH)
                down(n);
        if(mid>=r)
                cos+=query(l,r,numl,numr,n*2);
        else if(mid<l)
                cos+=query(l,r,numl,numr,n*2+1);
        else
                {
                cos+=query(l,mid,numl,numr,n*2);
                cos+=query(mid+1,r,numl,numr,n*2+1);
        }
        return cos;
        
}
int main()
{
        long long  i,n,m,l,r,numl,numr,num;
        char c[5];
        long long k;
        while(scanf("%lld%lld",&n,&m)>0)
        {
                for(i=1;i<=n;i++)
                        scanf("%lld",&date[i]);
                build(1,n,1);
                getchar();
                for(i=1;i<=m;i++)
                {
                        scanf("%s",c);
                        if(c[0]=='Q')
                        {
                                scanf("%lld%lld%lld%lld",&l,&r,&numl,&numr);
                                k=query(l,r,numl,numr,1);
                                printf("%lld\n",k);
                        }
                        else if(c[0]=='C')
                        {
                                scanf("%lld%lld%lld",&l,&r,&num);
                                update(l,r,num,1);
                        }
                }
        }
        return 0;
}

 

转载于:https://www.cnblogs.com/tom987690183/archive/2013/04/27/3047575.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值