HDU 4533 威威猫系列故事——晒被子
扫描线可做,然后当时比赛后问虎哥,他说可以标记,然后拖了很久,今天从早上折腾到晚上,终于把两种情况写出来,分析太弱。改天扫描线,再来一次。
被子如果被y = x 穿过,可以分成两部分,上和下,很容易发现这两部分,都是以1递增的,画画图,更好理解,这样注意很多特殊的情况,例如,分不成上下部分,还有穿过后,多着一部分,讨论各种情况就好,静下心来,仔细分析。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 #define N 200100 8 #define LL __int64 9 LL num[N],flag[N]; 10 int p[N]; 11 LL ans[N],x; 12 int main() 13 { 14 int cas,i,n,m,maxz1,minz1,maxz2,minz2; 15 int x1,y1,x2,y2; 16 scanf("%d",&cas); 17 while(cas--) 18 { 19 memset(flag,0,sizeof(flag)); 20 memset(num,0,sizeof(num)); 21 scanf("%d",&n); 22 for(i = 0;i < n;i ++) 23 { 24 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 25 if(y1 >= x2) 26 { 27 num[y1+1] += x2-x1; 28 num[y2+1] -= x2-x1; 29 } 30 else if(x1 >= y2) 31 { 32 num[x1+1] += y2-y1; 33 num[x2+1] -= y2-y1; 34 } 35 else 36 { 37 maxz1 = max(x1,y1); 38 minz1 = min(x1,y1); 39 flag[maxz1+2] += 2; 40 num[maxz1+1] += maxz1-minz1+1; 41 maxz2 = max(x2,y2); 42 minz2 = min(x2,y2); 43 flag[minz2+1] -= 2; 44 if(x2 > y2) 45 { 46 num[y2+1] -= y2-x1-1; 47 num[x2+1] -= y2-y1; 48 } 49 else 50 { 51 num[x2+1] -= x2-y1-1; 52 num[y2+1] -= x2-x1; 53 } 54 } 55 } 56 scanf("%d",&m); 57 for(i = 0;i < m;i ++) 58 scanf("%d",&p[i]); 59 x = 0; 60 for(i = 1;i <= p[m-1];i ++) 61 { 62 flag[i] = flag[i] + flag[i-1]; 63 x = x + num[i] + flag[i]; 64 ans[i] = ans[i-1] + x; 65 } 66 for(i = 0;i < m;i ++) 67 { 68 printf("%I64d\n",ans[p[i]]); 69 } 70 } 71 return 0; 72 } 73 /* 74 1 75 1 76 1 1 3 10 77 4 78 6 79 7 80 8 81 10 82 83 84 1 85 1 86 1 2 5 4 87 4 88 6 89 7 90 8 91 10 92 */