CSU 1487 未覆盖顶点数量
Description
有N个顶点,每个顶点有一个权值,初始值皆为0。接下来有M次操作,操作内容为 [a,b) or [b,a),将区间内顶点i 权值置为1,求最后顶点权值为0的数量。
Input
多组测试数据。
第一行为两个整数n, m,n(1<=n<=20000)表示顶点, m(1<=m<=50000)表示操作次数。
接下来包含m行,每行包含两个正整数 a,b属于区间[1,n] ,意义如上所述。
Output
每组测试输出一行,包含一个整数,表示顶点值为0的数量。
Sample Input
3 1 1 2 3 1 1 3
Sample Output
2 1 解题思路: 一看到这题可能就会容易想到应该用树状数组来解,我一开始也是这样想的,但如果每做一次操作都要对树状数组更新一次的话,这样 极有可能会TLE,所以只好另辟蹊径了。
方法是将每次操作的区间的前一个数的对应位置的值记为区间的后一个数的值,在做完所有的操作之后 对记录的数组扫一遍,当用一个max记录区间左端点最小的区间的右端点的值,当扫
记录数组的时候遇到某个位置的值比max大的时候就将max进行更新, 当所走到的这个位置的下标比max小的时候就将sum加一,最后sum的值即为值为1 的点的个数,这样值为0的点的个
数用n减掉sum就可以啦
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stdio.h> 2 #include<string.h> 3 int A[20005],n,m; 4 int main() { 5 while(scanf("%d%d",&n,&m)!=EOF) { 6 memset(A,0,sizeof(A)); 7 int x,y; 8 int min; 9 if(m!=0) { 10 scanf("%d%d",&x,&y); 11 if(x>y) { 12 int d=x; 13 x=y; 14 y=d; 15 } 16 A[x]=y; 17 min=x; 18 } 19 m--; 20 while(m>0) { 21 scanf("%d%d",&x,&y); 22 if(x>y) { 23 int d=x; 24 x=y; 25 y=d; 26 } 27 if(y>A[x]) 28 A[x]=y; 29 if(x<min) 30 min=x; 31 m--; 32 } 33 int max=A[min]; 34 int sum=0; 35 for(int i=1;i<=n;++i) { 36 if(A[i]>max) 37 max=A[i]; 38 if(max>i&&i>=min) 39 sum++; 40 } 41 int ans=n-sum; 42 printf("%d\n",ans); 43 } 44 return 0; 45 }