洛谷 红魔馆OI 红色的幻想乡 [线段树]

题目传送门
我想到了两片红雾会抵消,相当于每次修改,对应行^=1,对应列^=1。
但是没有想到可以建立两棵线段树分别维护每行,每列有没有释放过红雾。
于是沙茶地建了个树套树+cdq分治光荣WA。

//直接上标答
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define lson (rt<<1)
#define rson ((rt<<1)|1)
#define mid ((l+r)>>1)
using namespace std;
int sumx[400011],sumy[400011];
int n,m,q,op,px1,py1,px2,py2;
void insx(int rt,int l,int r,int x)
{
    if(l==r)
    {
        sumx[rt]^=1;
        return;
    }
    if(x<=mid)insx(lson,l,mid,x);
    else insx(rson,mid+1,r,x);
    sumx[rt]=sumx[lson]+sumx[rson];
}
int quex(int rt,int l,int r,int L,int R)
{
    if(L<=l&&r<=R)return sumx[rt];
    if(mid+1>R)return quex(lson,l,mid,L,R);
    if(L>mid)return quex(rson,mid+1,r,L,R);
    return quex(lson,l,mid,L,R)+quex(rson,mid+1,r,L,R);
}
void insy(int rt,int l,int r,int x)
{
    if(l==r)
    {
        sumy[rt]^=1;
        return;
    }
    if(x<=mid)insy(lson,l,mid,x);
    else insy(rson,mid+1,r,x);
    sumy[rt]=sumy[lson]+sumy[rson];
}
int quey(int rt,int l,int r,int L,int R)
{
    if(L<=l&&r<=R)return sumy[rt];
    if(mid+1>R)return quey(lson,l,mid,L,R);
    if(L>mid)return quey(rson,mid+1,r,L,R);
    return quey(lson,l,mid,L,R)+quey(rson,mid+1,r,L,R);
}
int main()
{
    scanf("%d%d%d",&n,&m,&q);
    while(q--)
    {
        scanf("%d%d%d",&op,&px1,&py1);
        if (op==1) 
        {
            insx(1,1,n,px1);
            insy(1,1,m,py1);
        }
        else
        {
            scanf("%d%d",&px2,&py2);
            ll n1=quex(1,1,n,px1,px2),m1=quey(1,1,m,py1,py2);
            printf("%lld\n",n1*(ll)(py2-py1+1)+m1*(ll)(px2-px1+1)-n1*m1*2LL);
        }                     
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值