codevs1299 切水果

1299 切水果

 

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 大师 Master
 
 
 
题目描述 Description

简单的说,一共N个水果排成一排,切M次,每次切[L,R]区间的所有水果(可能有的水果被重复切),每切完一次输出剩下水果数量

数据已重新装配,不会出现OLE错误

时限和数据范围适当修改,避免数据包过大而浪费空间资源

输入描述 Input Description

第1行共包括2个正整数,分别为N,M。

接下来m行每行两个正整数L,R 

输出描述 Output Description

一共输出M行,每行输出切完之后剩下水果数量

样例输入 Sample Input

10 3

3 5

2 8

1 5

样例输出 Sample Output

7

3

2

数据范围及提示 Data Size & Hint

30%的数据满足N,M<=5,000

60%的数据满足N,M<=100,000

100% 的数据满足1<=L<=R<=N<=500,000,1<=M<=500,000

//这个题因为标记不大规范,RE了好久。其实可以不加标记 

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 500000

using namespace std;

int n,m,x,y;
struct node{
    int l,r,dis;bool flag;
}tre[maxn*4+100];

void build(int now,int l,int r) 
{
    tre[now].l=l;tre[now].r=r;
    tre[now].flag=false;
    if(l==r)
    {
        tre[now].dis=1;
        return;
    }
    int mid=(l+r)>>1;
    build(now<<1,l,mid);
    build(now<<1|1,mid+1,r);
    tre[now].dis=tre[now<<1].dis+tre[now<<1|1].dis;
}

void tree_flag(int now)
{
    tre[now<<1].flag=true;
    tre[now<<1|1].flag=true;
    tre[now<<1].dis=0;
    tre[now<<1|1].dis=0;
}

void Change(int now,int l,int r)
{
    if(l==tre[now].l&&r==tre[now].r)
    {
        tre[now].dis=0;
        tre[now].flag=true;
        return; 
    }
    if(tre[now].flag) return;//这句话不大懂。为什么if(tre[now].flag) tree_flag(now) 就RE? 
    int mid=(tre[now].l+tre[now].r)>>1;
    if(l>mid)Change(now<<1|1,l,r);
    else if(r<=mid)Change(now<<1,l,r);
    else
    {
        Change(now<<1,l,mid);
        Change(now<<1|1,mid+1,r);
    }
    tre[now].dis=tre[now<<1].dis+tre[now<<1|1].dis;
}

int main()
{
    scanf("%d%d",&n,&m);
    build(1,1,n);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        Change(1,x,y);
        printf("%d
",tre[1].dis);
    }
    return 0;
}
心若向阳,无谓悲伤
折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
原文地址:https://www.cnblogs.com/L-Memory/p/6337167.html