题意:有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这样就能准确地判断该点是否被覆盖了。
这种方法值得去体会啊!
#include<stdio.h>
#include<string.h>
int s[1000005];
int main()
{
int m,n,a,b;
while(scanf("%d%d",&m,&n)!=-1) //本题巧妙之处在于不要把每个点去更新
{
memset(s,0,sizeof(s)); //只要在更新点的头部+1,在尾部-1就行了。
while(n--) //只要对区间求和就行了。当有sum==0的时候。
{ //则该点没被覆盖过。
scanf("%d%d",&a,&b);
if(a>b)
{
int t=a;
a=b;
b=t;
}
s[a]+=1,s[b]-=1;
}
int j=0,sum=0;
for(int i=1;i<=m;i++)
{
sum+=s[i];
if(sum==0) j++;
}
printf("%d\n",j);
}
return 0;
}