#3083. 「GXOI / GZOI2019」与或和

题目大意

给定一个\(N\times N\)的矩阵,求所有子矩阵的\(AND(\&)\)之和、\(OR(|)\)之和。

数据范围

\(1\le N\le 10^3\),\(val_{(i,j)} \le 2^{31}-1\)。

题解

一眼题。

对于这种位运算的题,题都不用看完先想拆位,拆位可行那就拆,拆位不可行就不拆。

这里指的拆位可不可行具体指的是答案满不满足对于拆位之后的可加性。

发现这个题所求的是个和,那就果断拆开。

这样的话问题就变成了给定一个\(01\)矩阵求\(AND\)和(\(OR\)同理)。

发现只要是子矩阵中有\(0\)就是\(0\)。

这种存在即可的式子最\(gay\)了。

绝大多数这种存在即可的式子都会依照“正难则反”变成“不存在即可”。

故此我们只需要求全\(1\)子矩阵个数。

这就很好求了,给定一个边长最多是\(1000\)的正方形\(01\)矩阵,问全\(1\)子矩阵个数。

每一行拿单调栈扫一扫就好了。

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
#define N 1010
int ori[N][N],a[N][N],bfr_up[N][N],bfr[N],aft[N],q[N],top;
int bin[31];
const int mod = 1000000007 ;
const int inv4 = 250000002 ;
char *p1,*p2,buf[1000000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++)
int rd() {int x=0; char c=nc(); while(c<48) c=nc(); while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x;}
int main()
{
bin[0]=1; for(int i=1;i<=30;i++) bin[i]=bin[i-1]<<1;
int n=rd();
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) ori[i][j]=rd();
int ans1=0,ans2=0;
for(int bt=0;bt<=30;bt++)
{
int now1=0,now2=0;
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
{
a[i][j]=(ori[i][j]>>bt)&1;
if(a[i][j]) bfr_up[i][j]=bfr_up[i-1][j]+1; else bfr_up[i][j]=0;
}
for(int i=1;i<=n;i++)
{
top=0;
for(int j=n;j;j--)
{
while(top&&bfr_up[i][j]<bfr_up[i][q[top]]) bfr[q[top]]=j,top--;
q[++top]=j;
}
while(top) bfr[q[top]]=0,top--;
top=0;
for(int j=1;j<=n;j++)
{
while(top&&bfr_up[i][j]<=bfr_up[i][q[top]]) aft[q[top]]=j,top--;
q[++top]=j;
}
while(top) aft[q[top]]=n+1,top--;
for(int j=1;j<=n;j++) (now1+=(ll)bfr_up[i][j]*(aft[j]-j)*(j-bfr[j])%mod)%=mod;
}
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
{
a[i][j]^=1;
if(a[i][j]) bfr_up[i][j]=bfr_up[i-1][j]+1; else bfr_up[i][j]=0;
}
for(int i=1;i<=n;i++)
{
top=0;
for(int j=n;j;j--)
{
while(top&&bfr_up[i][j]<bfr_up[i][q[top]]) bfr[q[top]]=j,top--;
q[++top]=j;
}
while(top) bfr[q[top]]=0,top--;
top=0;
for(int j=1;j<=n;j++)
{
while(top&&bfr_up[i][j]<=bfr_up[i][q[top]]) aft[q[top]]=j,top--;
q[++top]=j;
}
while(top) aft[q[top]]=n+1,top--;
for(int j=1;j<=n;j++) (now2+=(ll)bfr_up[i][j]*(aft[j]-j)*(j-bfr[j])%mod)%=mod;
}
now1=(ll)now1*bin[bt]%mod;
now2=(ll)now2*bin[bt]%mod;
(ans1+=now1)%=mod;
(ans2+=((ll)n * n * (n + 1) * (n + 1) % mod * inv4 % mod * bin[bt] % mod-now2 + mod)%mod)%=mod;
}
printf("%d %d\n",ans1,ans2);
return 0;
}

小结

模拟赛中被卡常了,\(LOJ\)也被卡常了。

这种取\(mod\)的题少取两次\(mod\)就好了。

LOJ#3083.「GXOI / GZOI2019」与或和_单调栈_拆位的更多相关文章

  1. LOJ#3083. 「GXOI / GZOI2019」与或和(单调栈)

    题面 传送门 题解 按位考虑贡献,如果\(mp[i][j]\)这一位为\(1\)就设为\(1\)否则设为\(0\),对\(or\)的贡献就是全为\(1\)的子矩阵个数,对\(and\)的贡献就是总矩阵 ...

  2. 「洛谷5300」「GXOI/GZOI2019」与或和【单调栈+二进制转化】

    题目链接 [洛谷传送门] 题解 按位处理. 把每一位对应的图都处理出来 然后单调栈处理一下就好了. \(and\)操作处理全\(1\). \(or\)操作处理全\(0\). 代码 #include & ...

  3. 【LOJ】#3083. 「GXOI / GZOI2019」与或和

    LOJ#3083. 「GXOI / GZOI2019」与或和 显然是先拆位,AND的答案是所有数字为1的子矩阵的个数 OR是所有的子矩阵个数减去所有数字为0的子矩阵的个数 子矩阵怎么求可以记录每个位置 ...

  4. Loj #3085. 「GXOI / GZOI2019」特技飞行

    Loj #3085. 「GXOI / GZOI2019」特技飞行 题目描述 公元 \(9012\) 年,Z 市的航空基地计划举行一场特技飞行表演.表演的场地可以看作一个二维平面直角坐标系,其中横坐标代 ...

  5. LOJ#3088. 「GXOI / GZOI2019」旧词(树剖+线段树)

    题面 传送门 题解 先考虑\(k=1\)的情况,我们可以离线处理,从小到大对于每一个\(i\),令\(1\)到\(i\)的路径上每个节点权值增加\(1\),然后对于所有\(x=i\)的询问查一下\(y ...

  6. LOJ#3087. 「GXOI / GZOI2019」旅行者(最短路)

    题面 传送门 题解 以所有的感兴趣的城市为起点,我们正着和反着各跑一边多源最短路.记\(c_{0/1,i}\)分别表示正图/反图中离\(i\)最近的起点,那么对于每条边\((u,v,w)\),如果\( ...

  7. LOJ#3086. 「GXOI / GZOI2019」逼死强迫症(矩阵快速幂)

    题面 传送门 题解 先考虑全都放\(1\times 2\)的方块的方案,设防\(i\)列的方案数为\(g_i\),容易推出\(g_i=g_{i-1}+g_{i-2}\),边界条件为\(g_0=g_1= ...

  8. LOJ#3085. 「GXOI / GZOI2019」特技飞行(KDtree+坐标系变换)

    题面 传送门 前置芝士 请确定您会曼哈顿距离和切比雪夫距离之间的转换,以及\(KDtree\)对切比雪夫距离的操作 题解 我们发现\(AB\)和\(C\)没有任何关系,所以关于\(C\)可以直接暴力数 ...

  9. LOJ#3084. 「GXOI / GZOI2019」宝牌一大堆(递推)

    题面 传送门 题解 为什么又是麻将啊啊啊!而且还是我最讨厌的爆搜类\(dp\)-- 首先国士无双和七对子是可以直接搞掉的,关键是剩下的,可以看成\(1\)个雀头加\(4\)个杠子或面子 直接\(dp\ ...

随机推荐

  1. python之dic {字典}(重要指数*****)

    1. 什么是字典 {'name': '汪峰', 'age': 18} '键':'值' 别的语言键值对数据 键: 必须是可哈希(不可变的数据类型),并且是唯一的 值: 任意 可以保存任意类型的数据 字典 ...

  2. ECMAScript 继承机制实现

    继承机制的实现 要用 ECMAScript 实现继承机制,您可以从要继承的基类入手.所有开发者定义的类都可作为基类.出于安全原因,本地类和宿主类不能作为基类,这样可以防止公用访问编译过的浏览器级的代码 ...

  3. LeetCode 字符串相乘

    给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式. 示例 1: 输入: num1 = "2", num ...

  4. codevs 数字三角形集结

    添在前面的一句话:初学DP,若有错误,请指出,不能误人子弟,欢迎大家提出意见.水平不高,博客写的比较粗糙,代码也挺丑,请见谅. 最原始的数字三角形: 1220 数字三角形  时间限制: 1 s  空间 ...

  5. (61)zabbix网络发现规则配置实战/详解

    开始配置.首先,我们需要定义发现规则,用于扫描.步骤如下 第一步 Configuration >>Discovery>>Create rule,编辑网络发现规则 如上配置,za ...

  6. 对于js运动中产生的问题

    1.不同的对象调用同一个定时器情况,则需要将定时器的名称定为该对象的一个属性来进行运用. 例: <!DOCTYPE html> <html lang="en"&g ...

  7. python 学习第二周总复习

    目录 数据类型内置方法 数字类型内置方法 整型 浮点型 字符串类型内置方法 列表类型内置方法 元祖类型内置方法 字典类型内置方法 集合类型内置方法 布尔类型 数据类型总结 拷贝 浅拷贝 深拷贝 053 ...

  8. leetcode刷题——双指针

    知识点 专题-B-双指针 题目: 题解: CS-Notes Algorithm_Interview_Notes-Chinese awesome-algorithm zcy19941015的博客

  9. HDU 3045 DP 斜率优化 Picnic Cows

    题意:将n个数分成若干组,每组数字的个数不少于t个,要把每组的数字减小到这组最小值,求所有数字减少的最小值. 先将这n个数从小到大排个序,可以想到一组里面的数一定是排序后相邻的. 设d(i)表示前i个 ...

  10. maven 打某一个模块的包

    mvn clean mvn clean install -pl benefit-microservice-gateway -am -Dmaven.test.skip=true