P3801 红色的幻想乡

P3801 红色的幻想乡


题意

给定 m 次操作:

  • 给出 (x,y) 将第 x 行第 y 列反转(将0变成1,将1变成0)。
  • 给出 (x1,y1) 和 (x2,y2) ,表示查询两点围成的矩阵中有多少个1。

分析

树状数组/线段树。

直接分别维护行列的0/1情况,分别计算行与列的贡献再减去相交处重复计算的贡献即可。

Codes:

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+100,M=5e5;
typedef long long ll;
int n,m,q,lim;
int g[N],h[2][N],b[2]={1,-1};
struct operation
{
int dx[2],dy[2],opt;
}f[N];
struct indextree
{
int c[2][N];
int lowbit(int x){return x&(-x);}
void upd(int x,int opt,int z)
{
if(x<1)return ;
while(x<=lim)
{
c[opt][x]+=z;
x+=lowbit(x);
}
}
int que(int x,int opt)
{
if(x<1)return 0;
int sum=0;
while(x)
{
sum+=c[opt][x];
x-=lowbit(x);
}
return sum;
}
}T;
void init()
{
scanf("%d%d%d",&n,&m,&q);
for(int i=1,opt,x,y;i<=q;++i)
{
scanf("%d%d%d",&opt,&x,&y);
f[i].opt=opt;
f[i].dx[0]=x;
f[i].dy[0]=y;
g[++g[0]]=x;
g[++g[0]]=y;
if(opt==2)
{
scanf("%d%d",&x,&y);
f[i].dx[1]=x;
f[i].dy[1]=y;
g[++g[0]]=x;
g[++g[0]]=y;
}
}
}
int got(int x)
{
return lower_bound(g+1,g+1+lim,x)-g;
}
void loading()
{
sort(g+1,g+1+g[0]);
lim=unique(g+1,g+1+g[0])-g-1;
}
void work()
{
for(int i=1,x,y;i<=q;++i)
{
if(f[i].opt==1)
{
x=got(f[i].dx[0]);
y=got(f[i].dy[0]);
T.upd(x,0,b[h[0][x]]);
T.upd(y,1,b[h[1][y]]);
h[0][x]^=1;
h[1][y]^=1;
}
else
{
ll sum1=0,sum2=0;
ll len1=f[i].dx[1]-f[i].dx[0]+1;
ll len2=f[i].dy[1]-f[i].dy[0]+1;
x=got(f[i].dx[0]);
y=got(f[i].dx[1]);
sum1=T.que(y,0)-T.que(x-1,0);
x=got(f[i].dy[0]);
y=got(f[i].dy[1]);
sum2=T.que(y,1)-T.que(x-1,1);
printf("%lld\n",sum1*len2+sum2*len1-2ll*sum1*sum2);
}
}
}
int main()
{
init();
loading();
work();
return 0;
}
posted @   Glowingfire  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
点击右上角即可分享
微信分享提示