区间覆盖的判断技巧
题意:有N个顶点,每个顶点有一个权值,初始值皆为0。接下来有M次操作,操作内容为 [a,b) or [b,a),将区间内顶点i 权值置为1,求最后顶点权值为0的数量。
多组测试数据。
第一行为两个整数n, m,n(1<=n<=20000)表示顶点, m(1<=m<=50000)表示操作次数。
接下来包含m行,每行包含两个正整数 a,b属于区间[1,n] ,意义如上所述。
每组测试输出一行,包含一个整数,表示顶点值为0的数量。
输入 3 1 1 2 3 1 1 3
输出 2
1
分析:本题在于一个技巧,把要覆盖的区间头部+1,尾部-1,求没被覆盖的点,
只要求和,判断sum[i]==0,如果是表明没覆盖,否则,就覆盖了。
这大楷就是因为区间有头有尾,1与-1,能抵消。当后面没覆盖,sum的值
过了覆盖区间的尾部,值变为0以了。而0+0=0这样就能准确地判断该点是否被覆盖了。
这种方法值得去体会啊!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stdio.h> 2 #include<string.h> 3 int s[1000005]; 4 int main() 5 { 6 int m,n,a,b; 7 while(scanf("%d%d",&m,&n)!=-1) //本题巧妙之处在于不要把每个点去更新 8 { 9 memset(s,0,sizeof(s)); //只要在更新点的头部+1,在尾部-1就行了。 10 while(n--) //只要对区间求和就行了。当有sum==0的时候。 11 { //则该点没被覆盖过。 12 scanf("%d%d",&a,&b); 13 if(a>b) 14 { 15 int t=a; 16 a=b; 17 b=t; 18 } 19 s[a]+=1,s[b]-=1; 20 } 21 int j=0,sum=0; 22 for(int i=1;i<=m;i++) 23 { 24 sum+=s[i]; 25 if(sum==0) j++; 26 } 27 printf("%d\n",j); 28 } 29 return 0; 30 }