luogu P3801 红色的幻想乡

二次联通门 : luogu P3801 红色的幻想乡

 

 

 

 

/*
    luogu P3801 红色的幻想乡

    两颗线段树
    
    分别维护 X方向和Y方向
    
    操作1就是异或1
    
    操作2用容斥搞一搞就好 
*/
#include <cstdio>

void read (int &now)
{
    now = 0;
    register char word = getchar ();
    while (word < '0' || word > '9')
        word = getchar ();
    while (word >= '0' && word <= '9')
    {
        now = now * 10 + word - '0';
        word = getchar ();
    }
}

struct S_D 
{
    S_D *Left, *Right;
    
    int key;
    int Mid;
    
    int l, r;
    S_D (int __l, int __r) : l (__l), r (__r), key (0) 
    {
        Mid = (__l + __r) >> 1;
        Left = Right = NULL;
    };
    
    S_D () {};
    
    inline void Updata ()
    {
        this->key = this->Left->key + this->Right->key;
    }
};


class Segment_Tree_Type
{
    
    private :
        
        S_D *Root;
        
        void __Build_ (S_D *&now, int l, int r)
        {
            now = new S_D (l, r);
            
            if (l == r)
                return ;
                
            __Build_ (now->Left, l, now->Mid);
            __Build_ (now->Right, now->Mid + 1, r);
            
            now->Updata ();
        }
        
        int Query (S_D *&now, int l, int r)
        {
            if (l <= now->l && now->r <= r)
                return now->key;
                
            register int res = 0;
            if (l <= now->Mid)
                res += Query (now->Left, l, r);
            if (r > now->Mid)
                res += Query (now->Right, l, r);
            
            return res;
        }
        
        void __Change_ (S_D *&now, int pos)
        {
            if (now->l == now->r)
            {
                now->key ^= 1;
                return ;
            }
            
            if (pos <= now->Mid)
                __Change_ (now->Left, pos);
            else
                __Change_ (now->Right, pos);
            
            now->Updata ();
        }
        
    public :
        
        inline void Build (int l, int r)
        {
            __Build_ (Root, l, r);
            return ;
        }
        
        inline void Change (int pos)
        {
            __Change_ (Root, pos);
            return ;
        }
        
        inline int Query (int l, int r)
        {
            return Query (Root, l, r);
        }
};

Segment_Tree_Type X, Y;

int main (int argc, char *argv[])
{
    int M, N, x, y;
    read (N);
    read (M);
    
    X.Build (1, N);
    Y.Build (1, M);
    
    int type, Q;
    
    int _x, _y;
    long long now_1, now_2;
    
    for (read (Q); Q --; )
    {
        read (type);
        read (x);
        read (y);
        
        if (type == 1)
        {
            X.Change (x);
            Y.Change (y);
        }
        else
        {
            read (_x);
            read (_y);
            
            now_1 = X.Query (x, _x);
            now_2 = Y.Query (y, _y);
            
            printf ("%lld\n", now_1 * (long long) (_y - y + 1) + now_2 * (long long) (_x - x + 1) - now_1 * now_2 * 2LL);
        }
    }
    
    return 0;
}

 

posted @ 2017-06-25 21:42  ZlycerQan  阅读(232)  评论(0编辑  收藏  举报