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 }
时间: 2024-10-08 09:47:02

codevs 1299 线段树 区间更新查询的相关文章

codevs 1191 线段树 区间更新(水)

题目描述 Description 在一条数轴上有N个点,分别是1-N.一开始所有的点都被染成黑色.接着我们进行M次操作,第i次操作将[Li,Ri]这些点染成白色.请输出每个操作执行后剩余黑色点的个数. 输入描述 Input Description 输入一行为N和M.下面M行每行两个数Li.Ri 输出描述 Output Description 输出M行,为每次操作后剩余黑色点的个数. 样例输入 Sample Input 10 33 35 72 8 样例输出 Sample Output 963 数据

POJ 2777 Count Color (线段树区间更新加查询)

Description Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem. There is a very long board with length L centimeter, L is a positive integer, so we can evenly d

ZOJ - 1610 Count the Colors(线段树区间更新,单点查询)

1.给了每条线段的颜色,存在颜色覆盖,求表面上能够看到的颜色种类以及每种颜色的段数. 2.线段树区间更新,单点查询. 但是有点细节,比如: 输入: 2 0 1 1 2 3 1 输出: 1 2 这种情况就需要处理一下,代码中把所有的左端点都+1,避免了这种情况. 3. #include<iostream> #include<stdio.h> #include<string.h> using namespace std; #define L(root) ((root) &l

Light OJ 1080 - Binary Simulation - (线段树区间更新 单点查询)

Description Given a binary number, we are about to do some operations on the number. Two types of operations can be here. 'I i j'    which means invert the bit from i to j (inclusive) 'Q i'    answer whether the ith bit is 0 or 1 The MSB (most signif

Hdu 3966 Aragorn&#39;s Story (树链剖分 + 线段树区间更新)

题目链接: Hdu 3966 Aragorn's Story 题目描述: 给出一个树,每个节点都有一个权值,有三种操作: 1:( I, i, j, x ) 从i到j的路径上经过的节点全部都加上x: 2:( D, i, j, x ) 从i到j的路径上经过的节点全部都减去x: 3:(Q, x) 查询节点x的权值为多少? 解题思路: 可以用树链剖分对节点进行hash,然后用线段树维护(修改,查询),数据范围比较大,要对线段树进行区间更新 1 #include <cstdio> 2 #include

HDU 5023 A Corrupt Mayor&#39;s Performance Art(线段树区间更新)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 解题报告:一面墙长度为n,有N个单元,每个单元编号从1到n,墙的初始的颜色是2,一共有30种颜色,有两种操作: P a b c  把区间a到b涂成c颜色 Q a b 查询区间a到b的颜色 线段树区间更新,每个节点保存的信息有,存储颜色的c,30种颜色可以压缩到一个int型里面存储,然后还有一个tot,表示这个区间一共有多少种颜色. 对于P操作,依次往下寻找,找要更新的区间,找到要更新的区间之前

POJ 3468 A Simple Problem with Integers(线段树区间更新)

题目地址:POJ 3468 打了个篮球回来果然神经有点冲动..无脑的狂交了8次WA..居然是更新的时候把r-l写成了l-r... 这题就是区间更新裸题.区间更新就是加一个lazy标记,延迟标记,只有向下查询的时候才将lazy标记向下更新.其他的均按线段树的来就行. 代码如下: #include <iostream> #include <cstdio> #include <cstring> #include <math.h> #include <stac

HDU 1698 Just a Hook (线段树,区间更新)

Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 17214    Accepted Submission(s): 8600 Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing f

PKU 2777 Count Color (线段树区间更新)

题意: 给你三个数:L (1 <= L <= 100000), T (1 <= T <= 30) and O (1 <= O <= 100000),表示有一长度为L的板(1~L), 有T种颜色(1~T),然后有O个操作,初始板1~L的颜色为1,"C A B C"表示在区间A,B图上C颜色, "P A B" 表示询问 A,B区间有几种不同的颜色. #include <stdio.h> #include <iostr