题面

思路还是挺容易想的, 只是由于我还是太\(naive\)了一点不会做只会打暴力吧......

题目要我们求所有子矩阵的\(and\)值之和与\(or\)值之和, 一看之下似乎不好入手, 我们慢慢来.

由于\(and\)和\(or\)运算都是对于每个数的同一位二进制位进行运算的, 所以我们考虑将每个数拆成二进制数, 一位一位地统计答案, 这样的话, 原矩阵就变成了\(log{n}\)个01矩阵, 我们考虑先从\(and\)值入手.

关于\(and\)值

由于是01矩阵, 对于最终答案有贡献的子矩阵必然所有元素都为1, 也就是说, 题目让我们求在一个\(n*m\)的矩阵中全为1的子矩阵有多少个. 这不是极大子矩阵的裸题吗, 考虑使用单调栈, 没有学过的左转百度吧(我也是昨天听\(lzf\)同志讲了我才知道的).

关于\(or\)值

其实差不多, 对答案没有贡献的矩形就是那些全部为0的矩形, 用所有的情况减掉就是了, 还是单调栈(熟悉的配方)

然后大体上题目分析就到这里了, 每一位复杂度是\(O(n ^ 2)\), 总复杂度为\(O(n ^ 2log{n})\), 下面是代码的具体实现:

#include <iostream>
#include <cstring>
#include <cstdio>
#define N 1005
#define mod 1000000007
using namespace std; int n, mp[N][N], s[N], w[N], h[N], top = 0;
long long ans[2]; inline int read()
{
int x = 0, w = 1;
char c = getchar();
while(c < '0' || c > '9') { if (c == '-') w = -1; c = getchar(); }
while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
return x * w;
} long long get_num(int x) { return (1ll * x * (x + 1)) >> 1; } long long get_ans(int x)
{
long long res = 0;
top = 0;
for(int i = 1; i <= n; i++) h[i] = 0;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if((mp[i][j] & 1) == x) h[j]++;
else h[j] = 0;
if(h[j] > s[top]) { s[++top] = h[j]; w[top] = 1; }
else
{
int k = 0;
while(s[top] > h[j])
{
k += w[top];
res = (res + (s[top] - max(s[top - 1], h[j])) * get_num(k) % mod) % mod;
top--;
}
s[++top] = h[j]; w[top] = k + 1;
}
}
int k = 0;
while(top)
{
k += w[top];
res = (res + (s[top] - s[top - 1]) * get_num(k) % mod) % mod;
top--;
}
}
return (res % mod + mod) % mod;
//单调栈实现极大子矩阵, 其实用悬线法也可以, 但是我既不会单调栈, 悬线法也没用过几次, 于是就成功Oho了
} void work(int x)
{
if(x == 32) return;
ans[0] = (ans[0] + get_ans(1) * (1 << x) % mod) % mod;
ans[1] = (ans[1] + (get_num(n) * get_num(n) % mod - get_ans(0)) * (1 << x) % mod) % mod;
//注意这个地方1左移x位是因为若不把这个数拆位的话其实这个数的这一位贡献是(1 << x)的.
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
mp[i][j] >>= 1;
work(x + 1);
} int main()
{
n = read();
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
mp[i][j] = read();
work(0);
printf("%lld %lld\n", (ans[0] + mod) % mod, (ans[1] + mod) % mod);
return 0;
}

[luogu 5300][bzoj 5502] [GXOI/GZOI2019] 与或和的更多相关文章

  1. [luogu 5301][bzoj 5503] [GXOI/GZOI2019] 宝牌一大堆

    题面 好像ZJOI也考了一道麻将, 这是要发扬中华民族的赌博传统吗??? 暴搜都不会打, 看到题目就自闭了, 考完出来之后看题解, \(dp\), 可惜自己想不出来... 对于国士无双(脑子中闪过了韩 ...

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

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

  3. 【BZOJ5505】[GXOI/GZOI2019]逼死强迫症(矩阵快速幂)

    [BZOJ5505][GXOI/GZOI2019]逼死强迫症(矩阵快速幂) 题面 BZOJ 洛谷 题解 如果没有那两个\(1*1\)的东西,答案就是斐波那契数,可以简单的用\(dp\)得到. 大概是设 ...

  4. 题解-GXOI/GZOI2019 特技飞行

    Problem loj3085 bzoj不放题面差评 题意概要:给出两条竖直直线,再给出 \(n\) 架飞机的初始航线:一条接通这两条直线的线段,保证航线交点不在两条直线上.现要求安排所有飞机在航线相 ...

  5. 【BZOJ5502】[GXOI/GZOI2019]与或和(单调栈)

    [BZOJ5502][GXOI/GZOI2019]与或和(单调栈) 题面 BZOJ 洛谷 题解 看到位运算就直接拆位,于是问题变成了求有多少个全\(0\)子矩阵和有多少个全\(1\)子矩阵. 这两个操 ...

  6. 【BZOJ5503】[GXOI/GZOI2019]宝牌一大堆(动态规划)

    [BZOJ5503][GXOI/GZOI2019]宝牌一大堆(动态规划) 题面 BZOJ 洛谷 题解 首先特殊牌型直接特判. 然后剩下的部分可以直接\(dp\),直接把所有可以存的全部带进去大力\(d ...

  7. 【BZOJ5506】[GXOI/GZOI2019]旅行者(最短路)

    [BZOJ5506][GXOI/GZOI2019]旅行者(最短路) 题面 BZOJ 洛谷 题解 正着做一遍\(dij\)求出最短路径以及从谁转移过来的,反过来做一遍,如果两个点不由同一个点转移过来就更 ...

  8. 【BZOJ5507】[GXOI/GZOI2019]旧词(树链剖分,线段树)

    [BZOJ5507][GXOI/GZOI2019]旧词(树链剖分,线段树) 题面 BZOJ 洛谷 题解 如果\(k=1\)就是链并裸题了... 其实\(k>1\)发现还是可以用类似链并的思想,这 ...

  9. [LOJ3087][GXOI/GZOI2019]旅行者——堆优化dijkstra

    题目链接: [GXOI/GZOI2019]旅行者 我们考虑每条边的贡献,对每个点求出能到达它的最近的感兴趣的城市(设为$f[i]$,最短距离设为$a[i]$)和它能到达的离它最近的感兴趣的城市(设为$ ...

随机推荐

  1. ASP.NET上传时间超过4M失败(超时)的解决方法

    https://blog.csdn.net/shan1774965666/article/details/20836851 在web.config中的<system.web></sy ...

  2. sql特殊语法

    MYSQL --判断非空select ifnull(null,'666');--666select ifnull(null,null);--null--合并字段select CONCAT('666', ...

  3. Repeater 控件的嵌套使用

      Repeater 控件的嵌套使用   ItemDataBound:数据绑定的时候(正在进行时)发生,多用在Repeater控件嵌套,对子Repeater控件进行数据绑定及模板列中统计列的计算处理等 ...

  4. [PHP] 数据结构-循环链表的PHP实现

    1.将单链表中终端结点的指针端由空指针改为指向头结点,单循环链表,循环链表和单链表的主要差异就在于循环的判断条件上原来是判断p->next是否为空,现在则是p->next不等于头结点,则循 ...

  5. 【Linux】Centos之安装Nginx及注意事项

    相关内容链接 [Linux]nginx常用命令 [nginx]详细配置说明 1.Nginx的简单说明 a.  Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务 ...

  6. 《深入理解Java虚拟机:JVM高级特性与最佳实践》读书笔记

    第一部分 走进Java 一.走进Java 1.概述 java广泛应用于嵌入式系统.移动终端.企业服务器.大型机等各种场合,摆脱了硬件平台的束缚,实现了“一次编写,到处运行”的理想 2.java技术体系 ...

  7. Centos7 firewalld 基本使用

    Centos7 的防火墙 firewalld比较常见 简单介绍使用 详细介绍链接推荐:   https://blog.csdn.net/buster_zr/article/details/806049 ...

  8. Python全栈学习_day004作业

    ,写代码,有如下列表,按照要求实现每一个功能 li = ["alex", "WuSir", "ritian", "barry&qu ...

  9. 初学HTML-6

    表单:专门用来收集用户信息 表单元素:在HTML中,标签/标记/元素都是指HTML中的标签. eg:<a>a标签/a标记/a元素 浏览器中所以得表单标签都有特殊的外观和默认的功能. 格式: ...

  10. Vue学习资料

    1. {{ msg }}插值表达式. v-text:将数据插入到页面中,没有闪烁问题. v-cloak:通过style属性选择器的方式display:none:防止闪烁问题. v-html:将标签解析 ...