您的位置:首页 > 其它

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

2017-07-09 14:41 218 查看
题目传送门

我想到了两片红雾会抵消,相当于每次修改,对应行^=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);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: