codevs 1299 线段树 区间更新查询
Posted 半根毛线code
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs 1299 线段树 区间更新查询相关的知识,希望对你有一定的参考价值。
题目描述 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 线段树 区间更新查询的主要内容,如果未能解决你的问题,请参考以下文章