• HDU1542矩形面积并


    取出纵向边按x坐标排序,在y方向上建立线段树。

    每次查询当前有效长度len,ans += len*(x[i]-x[i-1]); 其中len为T[rt].len;

    查询完毕后更新y方向上线段树,入边+1, 出边-1。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define lson l, m, rt<<1
     4 #define rson m+1, r, rt<<1|1
     5 typedef long long ll;
     6 struct L{
     7     double x, y1, y2;
     8     int d;
     9     L(){}
    10     L(double x, double y1, double y2, int d): x(x), y1(y1), y2(y2), d(d){}
    11 };
    12 L line[500];
    13 bool cmp(L A, L B){
    14     return A.x < B.x;
    15 }
    16 double y[500];
    17 
    18 struct Node{
    19     int d;
    20     double len;
    21 };
    22 Node T[500<<3];
    23 void init(){
    24     memset(T, 0, sizeof(T));
    25 }
    26 void pushup(int rt, int l, int r){
    27     if(T[rt].d)
    28         T[rt].len = y[r]-y[l-1];
    29     else
    30         T[rt].len = l == r? 0 : T[rt<<1].len+T[rt<<1|1].len;
    31 }
    32 void update(int L, int R, int d, int l, int r, int rt){
    33     if(L <= l&&r <= R){
    34         T[rt].d += d;
    35         pushup(rt, l , r);
    36         return ;
    37     }
    38     int m = (l+r)>>1;
    39     if(L <= m) update(L, R, d, lson);
    40     if(R > m) update(L, R, d, rson);
    41     pushup(rt, l, r);
    42 }
    43 
    44 int main(){
    45     int n, ca = 1;
    46     double x1, y1, x2, y2;
    47     while(scanf("%d", &n), n){
    48         for(int i = 0; i < n; i++){
    49             scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
    50             line[i*2] = L(x1, y1, y2, 1);
    51             line[i*2+1] = L(x2, y1, y2, -1);
    52             y[i*2] = y1, y[i*2+1] = y2;
    53         }
    54         sort(line, line+2*n, cmp);
    55         sort(y, y+2*n);
    56 
    57         init();
    58         double ans = 0;
    59         for(int i = 0; i < 2*n; i++){
    60             if(i&&line[i].x != line[i-1].x)
    61                 ans += (line[i].x-line[i-1].x)*T[1].len;
    62             int l = lower_bound(y, y+2*n, line[i].y1)-y+1, r = lower_bound(y, y+2*n, line[i].y2)-y;
    63             if(l <= r)
    64                 update(l, r, line[i].d, 1, 2*n, 1);
    65         }
    66         printf("Test case #%d
    ", ca++);
    67         printf("Total explored area: %.2f
    
    ", ans);
    68     }
    69     return 0;
    70 }
    View Code

    无pushdown()函数,每条线段只存一次。d表示被覆盖的次数,len表示至少被覆盖一次的合法长度。详见pushup()函数。

    ans += T[1].len*(x[i]-x[i-1]);

    求面积交:方法同求面积并,外加len2表示至少被覆盖两次的合法长度,ans += T[1].len2*(x[i]-x[i-1]);

    求周长并:方法同面积并,扫描两次,分别沿x方向和y方向,每次加上  更新前后T[1].len的差值的绝对值。

  • 相关阅读:
    CF-1328 F. Make k Equal
    CF-1328 E. Tree Queries
    USACO_1.1_Greedy_Gift_Givers_(模拟+水题)
    USACO_1.1_Your_Ride_Is_Here_(字符串+水题)
    第3章 文件系统
    BZOJ_1629_[Usaco2007_Demo]_Cow_Acrobats_(贪心)
    BZOJ_1628_[Usaco2007_Demo]_City_skyline_(单调栈)
    BZOJ_1030_[JSOI2007]_文本生成器_(AC自动机+DP)
    BZOJ_1029_[JSOI2007]_建筑抢修_(贪心+优先队列)
    BZOJ_1028_[JSOI2007]_麻将_(模拟+贪心)
  • 原文地址:https://www.cnblogs.com/dirge/p/5874748.html
Copyright © 2020-2023  润新知