[luogu 5300][bzoj 5502] [GXOI/GZOI2019] 与或和
题面
思路还是挺容易想的, 只是由于我还是太\(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] 与或和的更多相关文章
- [luogu 5301][bzoj 5503] [GXOI/GZOI2019] 宝牌一大堆
题面 好像ZJOI也考了一道麻将, 这是要发扬中华民族的赌博传统吗??? 暴搜都不会打, 看到题目就自闭了, 考完出来之后看题解, \(dp\), 可惜自己想不出来... 对于国士无双(脑子中闪过了韩 ...
- 「洛谷5300」「GXOI/GZOI2019」与或和【单调栈+二进制转化】
题目链接 [洛谷传送门] 题解 按位处理. 把每一位对应的图都处理出来 然后单调栈处理一下就好了. \(and\)操作处理全\(1\). \(or\)操作处理全\(0\). 代码 #include & ...
- 【BZOJ5505】[GXOI/GZOI2019]逼死强迫症(矩阵快速幂)
[BZOJ5505][GXOI/GZOI2019]逼死强迫症(矩阵快速幂) 题面 BZOJ 洛谷 题解 如果没有那两个\(1*1\)的东西,答案就是斐波那契数,可以简单的用\(dp\)得到. 大概是设 ...
- 题解-GXOI/GZOI2019 特技飞行
Problem loj3085 bzoj不放题面差评 题意概要:给出两条竖直直线,再给出 \(n\) 架飞机的初始航线:一条接通这两条直线的线段,保证航线交点不在两条直线上.现要求安排所有飞机在航线相 ...
- 【BZOJ5502】[GXOI/GZOI2019]与或和(单调栈)
[BZOJ5502][GXOI/GZOI2019]与或和(单调栈) 题面 BZOJ 洛谷 题解 看到位运算就直接拆位,于是问题变成了求有多少个全\(0\)子矩阵和有多少个全\(1\)子矩阵. 这两个操 ...
- 【BZOJ5503】[GXOI/GZOI2019]宝牌一大堆(动态规划)
[BZOJ5503][GXOI/GZOI2019]宝牌一大堆(动态规划) 题面 BZOJ 洛谷 题解 首先特殊牌型直接特判. 然后剩下的部分可以直接\(dp\),直接把所有可以存的全部带进去大力\(d ...
- 【BZOJ5506】[GXOI/GZOI2019]旅行者(最短路)
[BZOJ5506][GXOI/GZOI2019]旅行者(最短路) 题面 BZOJ 洛谷 题解 正着做一遍\(dij\)求出最短路径以及从谁转移过来的,反过来做一遍,如果两个点不由同一个点转移过来就更 ...
- 【BZOJ5507】[GXOI/GZOI2019]旧词(树链剖分,线段树)
[BZOJ5507][GXOI/GZOI2019]旧词(树链剖分,线段树) 题面 BZOJ 洛谷 题解 如果\(k=1\)就是链并裸题了... 其实\(k>1\)发现还是可以用类似链并的思想,这 ...
- [LOJ3087][GXOI/GZOI2019]旅行者——堆优化dijkstra
题目链接: [GXOI/GZOI2019]旅行者 我们考虑每条边的贡献,对每个点求出能到达它的最近的感兴趣的城市(设为$f[i]$,最短距离设为$a[i]$)和它能到达的离它最近的感兴趣的城市(设为$ ...
随机推荐
- [转]C#利用反射实现两个类的对象之间相同属性的值的复制
本文转自:https://blog.csdn.net/u013093547/article/details/53584591 在使用c#进行程序编写时,会遇到一个问题,两个属性字段差不多相同的类要进行 ...
- eclipse + maven搭建SSM框架
0.系统环境 1)Windows 10 企业版 2)JDK 1.8.0_131 3)Eclipse Java EE IDE for Web Developers Version: Neon.3 Re ...
- 详解promise、async和await的执行顺序
1.题目和答案 一道题题目:下面这段promise.async和await代码,请问控制台打印的顺序? async function async1(){ console.log('async1 sta ...
- SQL Server 基本INSERT语句
1.基本INSERT语句,单行插入 如果没有列出列,则使一一对应. 2.多行插入 3.INSERT INTO ... SELECT 语句 要插入的语句是从其他表中查询出来的. 注意:数据类型得相同或者 ...
- js之模态对话框
目标效果:点击页面按钮,显示模态对话框,在模态对话框里点击取消关闭模式对话框. 效果如下 实现代码如下: <!DOCTYPE html> <html lang="en&qu ...
- python之MRO和C3算法
python2类和python3类的区别pyhon2中才分新式类与经典类,python3中统一都是新式类Python 2.x中默认都是经典类,只有显式继承了object才是新式类python 3.x中 ...
- Android6.0源码下载编译刷入真机
编译环境是Ubuntu12.04.手机nexus 5,编译安卓6.0.1源码并烧录到真机. 源码用的是科大的镜像:http://mirrors.ustc.edu.cn/aosp-monthly/,下载 ...
- Asp.Net Core 使用Quartz基于界面画接口管理做定时任务
今天抽出一点点时间来造一个小轮子,是关于定时任务这块的. 这篇文章主要从一下几点介绍: 创建数据库管理表 创建web项目 引入quarzt nuget 包 写具体配置操作,实现定时任务处理 第一步:创 ...
- 数据层的多租户浅谈(SAAS多租户数据库设计)
在上一篇“浅析多租户在 Java 平台和某些 PaaS 上的实现”中我们谈到了应用层面的多租户架构,涉及到 PaaS.JVM.OS 等,与之相应的是数据层也有多租户的支持. 数据层的多租户综述 多租户 ...
- C#使用Aforge调用摄像头拍照
一. 新建一个Winform项目 二.使用Nuget添加引用 安装下图中红色框住的两个程序包 安装完后发现安装了如下图的程序包,这是因为上述两个程序包存在对其它程序包的依赖. 三.编写程序 1. 窗体 ...