[题解]P1856 [USACO5.5]矩形周长Picture

Loli 考试的题目之一

#include <cstdio>
#include <cstring>
#define re register
#define GC getchar()
#define Clean(X,K) memset(X,K,sizeof(X))
#include <iostream>
#define LS (RT*2)
#define RS (RT*2+1)
#include <algorithm>
#define Abs(X) ((X)<0?-(X):(X))
using namespace std ;
int Qread () {
    int X = 0 , F = 1;
    char C = GC ;
    while (C > '9' || C < '0') {
        if (C == '-') F = -1;
        C = GC ;
    }
    while (C >='0' && C <='9') {
        X = X * 10 + C - '0' ;
        C = GC ;
    }
    return X * F ;
}
const int MaxL = 100001 << 1 , Dlt = 100001;
struct Node {
    int Left , Right , Date , Tag ;
};
Node T[MaxL << 2] ;
int N ;
void Plant (int RT ,int L , int R) {
    T[RT].Date = R - L + 1 , T[RT].Tag = -1 ;
    T[RT].Left = L , T[RT].Right = R ;
    if (L == R) return ;
    int Mid = (L + R) >> 1 ;
    Plant (LS , L , Mid) , Plant (RS , Mid + 1 , R) ;
}
void Spd (int RT) {
    if (T[RT].Tag == 1) {
        T[LS].Date = T[LS].Right - T[LS].Left + 1 , T[RS].Date = T[RS].Right - T[RS].Left + 1 ;
        T[LS].Tag = T[RS].Tag = 1 ;
    }
    if (T[RT].Tag == 0) {
        T[LS].Date = T[RS].Date = 0 ;
        T[LS].Tag = T[RS].Tag = 0 ;
    }
    T[RT].Tag = -1 ;
}
int Ask (int RT ,int L , int R) {
    if (L <= T[RT].Left && T[RT].Right <= R) return T[RT].Date ;
    Spd(RT) ;
    int Al = 0 , Ar = 0 , Mid = (T[RT].Left + T[RT].Right ) >> 1 ;
    if (L <= Mid) Al = Ask (LS , L , R) ;
    if (R >  Mid) Ar = Ask (RS , L,  R);
    return Al + Ar ;
}
void Add (int RT , int L , int R , int K) {
    if (L <= T[RT].Left && T[RT].Right <= R) {
        T[RT].Date = (K ? T[RT].Right - T[RT].Left + 1 : 0) ;
        T[RT].Tag = K ;
        return ;
    }
    int Mid = (T[RT].Left + T[RT].Right ) >> 1 ;
    Spd(RT) ;
    if (L <= Mid) Add (LS , L , R , K) ;
    if (R >  Mid) Add (RS , L , R , K) ;
    T[RT].Date = T[LS].Date + T[RS].Date ;
}
struct Segment {
    int Place , From , Goto , Tag;
};
Segment X[MaxL] , Y[MaxL] ;
bool C (const Segment &X , const Segment &Y) {
    return X.Place < Y.Place ;
}
int A[MaxL] ;
int main () {
   // freopen ("P1856.in" , "r" , stdin) ;
    N = Qread () ;
    Plant (1 , 1 , N << 1);
    for (re int i = 1 ; i <= N; ++ i) {
        int A = Qread() + Dlt, B = Qread () + Dlt, C = Qread() + Dlt,D = Qread () + Dlt;
        X[i].From = X[i + N].From = Y[i].Place = A ;
        X[i].Goto = X[i + N].Goto = Y[i + N].Place = C ;
        Y[i].From = Y[i + N].From = X[i].Place = B ;
        Y[i].Goto = Y[i + N].Goto = X[i + N].Place = D ;
        X[i].Tag = Y[i].Tag = 1 , X[i + N].Tag = Y[i + N].Tag = -1 ;
        -- X[i].Goto , -- X[i + N].Goto , -- Y[i].Goto , -- Y[i + N].Goto ;
    }

    std :: sort (X + 1 , X + 1 + (N << 1) , C) ;
    std :: sort (Y + 1 , Y + 1 + (N << 1) , C) ;
    long long int Ans = 0 ;
    Clean (A , 0) ;
    for (re int i = 1 ; i <= 2 * N ; ++ i) {
        if (X[i].Tag == 1) {
            for (re int j = X[i].From ; j <= X[i].Goto ; ++ j) {
                if (A[j] == 0) ++ Ans ;
                ++ A[j] ;
            }
        } else {
            for (re int j = X[i].From ; j <= X[i].Goto ; ++ j) {
                -- A[j] ;
                if (A[j] == 0) ++ Ans ;
            }
        }
    }
    swap (X , Y) ;
    Clean(A , 0) ;
    for (re int i = 1 ; i <= 2 * N ; ++ i) {
        if (X[i].Tag == 1) {
            for (re int j = X[i].From ; j <= X[i].Goto ; ++ j) {
                if (A[j] == 0) ++ Ans ;
                ++ A[j] ;
            }
        } else {
            for (re int j = X[i].From ; j <= X[i].Goto ; ++ j) {
                -- A[j] ;
                if (A[j] == 0) ++ Ans ;
            }
        }
    }
    cout << Ans <<endl;
    fclose (stdin) ,fclose (stdout) ;
    return 0 ;
}

猜你喜欢

转载自www.cnblogs.com/bj2002/p/10511995.html
今日推荐