LOJ#3083.「GXOI / GZOI2019」与或和_单调栈_拆位
#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」与或和_单调栈_拆位的更多相关文章
- LOJ#3083. 「GXOI / GZOI2019」与或和(单调栈)
题面 传送门 题解 按位考虑贡献,如果\(mp[i][j]\)这一位为\(1\)就设为\(1\)否则设为\(0\),对\(or\)的贡献就是全为\(1\)的子矩阵个数,对\(and\)的贡献就是总矩阵 ...
- 「洛谷5300」「GXOI/GZOI2019」与或和【单调栈+二进制转化】
题目链接 [洛谷传送门] 题解 按位处理. 把每一位对应的图都处理出来 然后单调栈处理一下就好了. \(and\)操作处理全\(1\). \(or\)操作处理全\(0\). 代码 #include & ...
- 【LOJ】#3083. 「GXOI / GZOI2019」与或和
LOJ#3083. 「GXOI / GZOI2019」与或和 显然是先拆位,AND的答案是所有数字为1的子矩阵的个数 OR是所有的子矩阵个数减去所有数字为0的子矩阵的个数 子矩阵怎么求可以记录每个位置 ...
- Loj #3085. 「GXOI / GZOI2019」特技飞行
Loj #3085. 「GXOI / GZOI2019」特技飞行 题目描述 公元 \(9012\) 年,Z 市的航空基地计划举行一场特技飞行表演.表演的场地可以看作一个二维平面直角坐标系,其中横坐标代 ...
- LOJ#3088. 「GXOI / GZOI2019」旧词(树剖+线段树)
题面 传送门 题解 先考虑\(k=1\)的情况,我们可以离线处理,从小到大对于每一个\(i\),令\(1\)到\(i\)的路径上每个节点权值增加\(1\),然后对于所有\(x=i\)的询问查一下\(y ...
- LOJ#3087. 「GXOI / GZOI2019」旅行者(最短路)
题面 传送门 题解 以所有的感兴趣的城市为起点,我们正着和反着各跑一边多源最短路.记\(c_{0/1,i}\)分别表示正图/反图中离\(i\)最近的起点,那么对于每条边\((u,v,w)\),如果\( ...
- LOJ#3086. 「GXOI / GZOI2019」逼死强迫症(矩阵快速幂)
题面 传送门 题解 先考虑全都放\(1\times 2\)的方块的方案,设防\(i\)列的方案数为\(g_i\),容易推出\(g_i=g_{i-1}+g_{i-2}\),边界条件为\(g_0=g_1= ...
- LOJ#3085. 「GXOI / GZOI2019」特技飞行(KDtree+坐标系变换)
题面 传送门 前置芝士 请确定您会曼哈顿距离和切比雪夫距离之间的转换,以及\(KDtree\)对切比雪夫距离的操作 题解 我们发现\(AB\)和\(C\)没有任何关系,所以关于\(C\)可以直接暴力数 ...
- LOJ#3084. 「GXOI / GZOI2019」宝牌一大堆(递推)
题面 传送门 题解 为什么又是麻将啊啊啊!而且还是我最讨厌的爆搜类\(dp\)-- 首先国士无双和七对子是可以直接搞掉的,关键是剩下的,可以看成\(1\)个雀头加\(4\)个杠子或面子 直接\(dp\ ...
随机推荐
- 前台解析json的方法
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意 ...
- HDU-2544-最短路(floyd)
板子题,实验一下floyd. #include <cstdio> #include <algorithm> #include <cstring> using nam ...
- 八:SQL之DQL数据查询语言单表操作
前言: DQL数据库查询语言是我们在开发中最常使用的SQL,这一章总结了单表操作部分的常用查询方式 主要操作有:查询所有字段.查询指定字段.查询指定记录.带IN的关键字查询,范围查询,陪查询.查询空值 ...
- php登录加密加盐
1 背景 涉及身份验证的系统都需要存储用户的认证信息,常用的用户认证方式主要为用户名和密码的方式,为了安全起见,用户输入的密码需要保存为密文形式,可采用已公开的不可逆的hash加密算法 ...
- Flux reference
https://facebook.github.io/flux/docs/dispatcher.html#content 首先安装 npm install --save flux Dispatcher ...
- Linux文件权限与文件夹权限实践
文件权限在基础中有介绍,不在重复 一.文件夹权限: 示例: 解释说明: r --read 既ls w --write 既创建新的目录或者文件 x --execute 既cd 现在有4个用户分属 ...
- python 游戏(滑动拼图Slide_Puzzle)
1. 游戏功能和流程图 实现16宫格滑动拼图,实现3个按钮(重置用户操作,重新开始游戏,解密游戏),后续难度,额外添加重置一次的按钮,解密算法的植入,数字改变为图片植入 游戏流程图 2. 游戏配置 配 ...
- BFS:UVa220 ACM/ICPC 1992-Othello(黑白棋)
Othello Othello is a game played by two people on an 8 x 8 board, using disks that are white on one ...
- 三、harbor部署之SSL
1 签名证书与自签名证书 签名证书:由权威颁发机构颁发给服务器或者个人用于证明自己身份的东西. 自签名证书:由服务器自己颁发给自己,用于证明自己身份的东西,非权威颁发机构发布. 2 openssl简介 ...
- hdu2024
这题目感觉不是很严谨,如果是关键字的话也是不能作为合法标识符的,但是这个不用检测,就算要检测也会很费劲,还得用字符串匹配,而且还得知道一共都有哪些关键字,太麻烦了,所以出题人原意就是检查大小写字母数字 ...