codevs1299 切水果
题目描述 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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//这个题因为标记不大规范,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\n",tre[1].dis); } return 0; }
折花枝,恨花枝,准拟花开人共卮,开时人去时。
怕相思,已相思,轮到相思没处辞,眉间露一丝。