codevs 1299 线段树 区间更新查询

Posted 半根毛线code

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs 1299 线段树 区间更新查询相关的知识,希望对你有一定的参考价值。

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

题意:n个水果排成一排 m次查询 每次删除[L,R]区间内的水果 并输出剩下的水果的数量

题解:线段树处理 题目数据有问题 存在L<0   R>N的数据 

  1 /******************************
  2 code by drizzle
  3 blog: www.cnblogs.com/hsd-/
  4 ^ ^    ^ ^
  5  O      O
  6 ******************************/
  7 #include<bits/stdc++.h>
  8 #include<iostream>
  9 #include<cstring>
 10 #include<cstdio>
 11 #include<map>
 12 #include<algorithm>
 13 #include<queue>
 14 #define ll __int64
 15 using namespace std;
 16 struct node
 17 {
 18     int l,r;
 19     int w;
 20     int add;
 21 }tree[2000005];
 22 void buildtree(int root,int left,int right)
 23 {
 24     tree[root].l=left;
 25     tree[root].r=right;
 26     tree[root].add=0;
 27     if(left==right)
 28     {
 29         tree[root].w=1;
 30         return ;
 31     }
 32     int mid=(left+right)>>1;
 33     buildtree(root<<1,left,mid);
 34     buildtree(root<<1|1,mid+1,right);
 35     tree[root].w=tree[root<<1].w+tree[root<<1|1].w;
 36 }
 37 void pushdown(int root)
 38 {
 39     if(tree[root].add==0) return;
 40     tree[root<<1].add=1;
 41     tree[root<<1|1].add=1;
 42     tree[root].add=0;
 43     tree[root<<1].w=0;
 44     tree[root<<1|1].w=0;
 45 }
 46 void updata(int root,int left,int right,int c)
 47 {
 48     if(tree[root].l==left&&tree[root].r==right)
 49     {
 50         tree[root].add=c;
 51         tree[root].w=0;
 52         return ;
 53     }
 54     pushdown(root);
 55     int mid=(tree[root].l+tree[root].r)>>1;
 56     if(right<=mid)
 57     {
 58         updata(root<<1,left,right,c);
 59     }
 60     else
 61     {
 62         if(left>mid)
 63             updata(root<<1|1,left,right,c);
 64         else
 65         {
 66             updata(root<<1,left,mid,c);
 67             updata(root<<1|1,mid+1,right,c);
 68         }
 69     }
 70     tree[root].w=tree[root<<1].w+tree[root<<1|1].w;
 71 }
 72 int query(int root ,int  left,int right)
 73 {
 74     if(tree[root].l==left&&tree[root].r==right)
 75     {
 76         return tree[root].w;
 77     }
 78     pushdown(root);
 79     int mid=(tree[root].l+tree[root].r)>>1;
 80     if(mid<=right)
 81         return query(root<<1,left,right);
 82     else
 83     {
 84         if(left>mid)
 85             return query(root<<1|1,left,right);
 86         else
 87             return query(root<<1,left,mid)+query(root<<1|1,mid+1,right);
 88     }
 89 }
 90 int n,m;
 91 int le,ri;
 92 int main()
 93 {
 94     while(scanf("%d %d",&n,&m)!=EOF)
 95     {
 96         buildtree(1,1,n);
 97         for(int i=1;i<=m;i++)
 98         {
 99             scanf("%d %d",&le,&ri);
100             updata(1,max(1,le),min(n,ri),1);
101             printf("%d\\n",query(1,1,n));
102         }
103     }
104     return 0;
105 }

 

以上是关于codevs 1299 线段树 区间更新查询的主要内容,如果未能解决你的问题,请参考以下文章

[CodeVS1299]切水果

codevs 4927 线段树练习5

codevs 4927 线段树练习5 线段树基本操作模板

codevs 线段树练习5

codevs 4927 线段树练习5

线段树练习5(codevs 4927)