区间覆盖的判断技巧

题意:有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这样就能准确地判断该点是否被覆盖了。

这种方法值得去体会啊!

 

View Code
 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 }    

 

 

 

posted on 2013-04-15 21:10  青竹士  阅读(295)  评论(0编辑  收藏  举报

导航