题面

思路还是挺容易想的, 只是由于我还是太\(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. 探秘 Java 热部署三(Java agent agentmain)

    前言 让我们继续探秘 Java 热部署.在前文 探秘 Java 热部署二(Java agent premain)中,我们介绍了 Java agent premain.通过在main方法之前通过类似 A ...

  2. DotNetCore学习-1.读取Json配置并绑定到配置类实例

    DotNetCore的程序的配置不再完全局限于XML文件,增加更加通用的Json配置. 读取Json配置文件的类主要在Microsoft.Extensions.Configuration命名空间下,创 ...

  3. 学Java的18天,今天老师讲构造方法;

    上一篇讲到方法的调用和简单的构造方法,今天继续加深,加参数或者该参数: package sklx; public class Car{ //设三个属性 private String 品牌; priva ...

  4. Clock Pictures(kmp + Contest2075 - 湖南多校对抗赛(2015.04.26))

    Problem H: Clock Pictures Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 73  Solved: 18[Submit][Stat ...

  5. 设计模式之迭代器模式(Iterator)

    迭代器在STL运用广泛,类似容器的迭代已经成为其重要特性,而迭代器模式则是利用迭代器概念进行的抽象运用,迭代器模式运用广泛和有用,因为其能够不考虑数据的存储方式,而是直接面对数据进行迭代,也就是说我们 ...

  6. link标签链接CSS和@import加载的区别

    link:基本语法 <link rel="stylesheet" href="路径"> @import 基本语法 <style> @im ...

  7. Django基础篇--用户权限管理和组管理

    Django作为一个成熟的python后台开发框架,为开发者提供了很多内置的功能,开发者只需要做一些配置就可以完成原生操作中比较复杂的代码编写.这些内置功能中其中一个比较强大的功能就是后台用户管理类. ...

  8. [20180604]在内存修改数据(bbed).txt

    [20180604]在内存修改数据(bbed).txt --//以前曾经做过在内存修改数据,通过oradebug poke命令修改内存信息,相关链接:--//http://blog.itpub.net ...

  9. 洗礼灵魂,修炼python(43)--巩固篇—经典类/新式类

    经典类 1.什么是经典类 就是在使用class关键词时,括号内不添加object类的就叫经典类,前面的博文里是绝对解析过的,所以你应该知道,经典类现在已经仅存在于python2了,因为python3不 ...

  10. SQLserver 还原数据库报“指定转换无效”的错的解决方案

    最近在附加一个数据库的时候遇到一个问题:“指定转换无效”,经过分析,出现这个问题的原因可能是:1.版本不对.2.文件加密.3.文件损坏 解决方法: 一.版本不对: 1.   首先确定源数据库版本,下面 ...