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\ ...
随机推荐
- linux环境nginx的安装与使用
因为公司需要需要安装一系列环境,新手上路第一次配的时候什么也不懂在网上找了半天,觉得这篇不错,我在这里顺便记录一下.(原文:https://www.cnblogs.com/wyd168/p/66365 ...
- AR报表控件的常见问题汇总
1)字符串格式不正确 原因是建立报表时未使用分页报表 导致拖动数据为sum()表达式,sum运算字符串当然会出问题 2)超出索引 顾名思义 数据为空或不匹配 3)图片使用远程图片时记得把属性修改为远程 ...
- PAT (Basic Level) Practise (中文)-1027. 打印沙漏(20)
PAT (Basic Level) Practise (中文)-1027. 打印沙漏(20) http://www.patest.cn/contests/pat-b-practise/1027 本题 ...
- 八 个优秀的 jQuery Mobile 教程
jQuery Mobile 是 jQuery 在手机上和平板设备上的版本.jQuery Mobile不仅会给主流移动平台带来jQuery核心库,而且会发布一个完整统一的jQuery移动UI框架.虽然j ...
- shell脚本,按行读取文件的几种方法。
第一种方法用while实现按读取文件.[root@localhost wyb]# cat a.txt 第一行 aaaaaa 第二行 bbbbbb 第三行 cccccc 第四行 dddddd 第五行 e ...
- c++ 计算彩票中奖概率
操作方法: 输入两个数字,第一个数字是备选总数,第二个数字是选择总数,然后返回中将概率. 可以投注多次,结束的时候返回总的中将概率. #include <iostream> using n ...
- 【DB_MySQL】MySQL重要知识点
MySQL中的select语句 各子句的执行顺序 SELECT语句的处理过程 1. FROM 组装数据来源 2. WHERE筛选元组 3. GROUP BY 将满足条件的元组进行分组 4. HAVIN ...
- Java的BigDecimal容易出现的坑
BigDecimal一般是用来做要求比较高的精准计算的.前几天在使用的时候遇到一个大坑,记录下. 这个问题产生是使用BigDecimal做除法(divide)运算,这个类的divide方法存在三个常用 ...
- 收集自网络上有关Kali的各种源
更新源总结 #更新源 gedit /etc/apt/sources.list #中科大kali源 deb http://mirrors.ustc.edu.cn/kali kali-rollin ...
- vfs_caches_init函数解析
vfs_caches_init函数初始化VFS,下面梳理函数调用流程 start_kernel() -->vfs_caches_init_early(); -->dcache_init_e ...