#3083. 「GXOI / GZOI2019」与或和 题目大意 给定一个\(N\times N\)的矩阵,求所有子矩阵的\(AND(\&)\)之和.\(OR(|)\)之和. 数据范围 \(1\le N\le 10^3\),\(val_{(i,j)} \le 2^{31}-1\). 题解 一眼题. 对于这种位运算的题,题都不用看完先想拆位,拆位可行那就拆,拆位不可行就不拆. 这里指的拆位可不可行具体指的是答案满不满足对于拆位之后的可加性. 发现这个题所求的是个和,那就果断拆开. 这样的话问题就变…
题目链接 [洛谷传送门] 题解 按位处理. 把每一位对应的图都处理出来 然后单调栈处理一下就好了. \(and\)操作处理全\(1\). \(or\)操作处理全\(0\). 代码 #include <bits/stdc++.h> #define gc getchar using namespace std; typedef long long ll; const int N = 1000 + 4; const int P = 1e9 + 7; const int BIT = 31; int n…
题面 传送门 题解 按位考虑贡献,如果\(mp[i][j]\)这一位为\(1\)就设为\(1\)否则设为\(0\),对\(or\)的贡献就是全为\(1\)的子矩阵个数,对\(and\)的贡献就是总矩阵个数减去全为\(0\)的子矩阵个数,单调栈搞一搞就好了 //minamoto #include<bits/stdc++.h> #define R register #define inline __inline__ __attribute__((always_inline)) #define fp…
题目链接懒得放了. 题目大意懒得写了. 省选原题哪有找不到的…… 说实话,其实这题是个大水题,被我十秒钟内口胡出来了. 首先位运算除了拆位还能干啥?以下以与为例,或是差不多的. 我们考虑有多少个子矩阵会对这一位答案产生贡献,其实就是全 $1$ 的子矩阵. 问题转化为计算全 $1$ 子矩阵的个数. 这是一个简单题.考虑枚举右下角,发现包括这个右下角的子矩阵肯定长这样:(画的比较丑,意会就好了) 也就是高度单调递增. 高度可以做到 $O(1)$ 转移(从 $h[i-1][j]$)转移. 至于递增的高…
首先看到与或,很显然想到按照位拆分运算.然后就变成了0/1矩阵,要使矩阵在当前位与为1,则矩阵全为1,如果是或为1,则是矩阵不全为0,然后求全为0/1的矩阵个数即可.记录c[i][j]表示以a[i][j]在该位向上0/1的长度.然后对于每一行,单调栈求解即可. #include<bits/stdc++.h> using namespace std; ,mod=1e9+; int n,ans1,ans2,top,a[N][N],b[N][N],c[N][N],st[N],sum[N]; int…
题目链接: [GXOI/GZOI2019]与或和 既然求的是二进制运算的和,那么我们按位考虑,这样就将矩阵变成了一个$01$矩阵. 对于或运算,就是求有多少个子矩形中有$1$. 直接求不好办,考虑有多少个矩形只有$0$. 我们统计以每个$0$为矩形右下角的矩形有多少个. 对于第$i$行的每一列维护出从这一行开始往上有多少个连续的$0$. 现在问题就变成了对于第$i$行的每一列,之前有多少个格子能作为矩形的左上角和它匹配. 用单调栈维护一个单调递增的序列对每行分别统计答案即可. 对于与运算,就是将…
[BZOJ5502][GXOI/GZOI2019]与或和(单调栈) 题面 BZOJ 洛谷 题解 看到位运算就直接拆位,于是问题变成了求有多少个全\(0\)子矩阵和有多少个全\(1\)子矩阵. 这两个操作本质就是一样的,不妨考虑有多少个全\(1\)子矩阵. 预处理出每个元素向上能够找的最多的\(1\)的个数,对于每一行从做往右扫一遍,拿一个单调栈维护一下,这样子就可以计算出以每个元素为右下角时的贡献了. 时间复杂度\(O(n^2logV)\),在BZOJ上因为常数太大T了QwQ. #include…
LOJ BZOJ 洛谷 想了一个奇葩的单调栈,算的时候要在中间取\(\min\),感觉不靠谱不写了=-= 调了十分钟发现输出没取模=v= BZOJ好逗逼啊 题面连pdf都不挂了 哈哈哈哈 枚举每一位.在这一位上与之后得到\(1\)的就是全\(1\)子矩形个数.或之后得到\(1\)的就是总举行个数减去全\(0\)子矩形个数. 单调栈算一下就好啦. 维护一个单调递增的栈.如果在右下角统计贡献,每次遇到往上延伸长度\(l\leq sk[top]\)时,会把\(sk[top]\)的一部分截断.用个变量\…
想了想决定把这几题也随便水个解题报告... bzoj  luogu 思路: 首先肯定得拆成二进制30位啊 此后每一位的就是个01矩阵 Q1就是全是1的矩阵个数 Q2就是总矩阵个数减去全是0的矩阵个数 玉蟾宫警告 就是单调栈乱搞对吧 本题完结 事实上有了思路其他的都是多余的对吧所以就不要介意代码了 #include<cstdio> #define mo 1000000007 ; template<typename tp>inline void read(tp &tar) {…
题目地址:P5300 [GXOI/GZOI2019]与或和 考虑按位计算贡献 对于 AND 运算,只有全 \(1\) 子矩阵才会有贡献 对于 OR 运算,所以非全 \(0\) 子矩阵均有贡献 如果求一个 01 矩阵中全 \(0/1\) 子矩阵的个数呢? 单调栈可以 \(O(n^2)\) 实现 总时间复杂度 \(O(n^2k)\) 其中 \(k\) 是二进制位数 #include <bits/stdc++.h> #define ll long long using namespace std;…
「GXOI / GZOI2019」简要题解 LOJ#3083. 「GXOI / GZOI2019」与或和 https://loj.ac/problem/3083 题意:求一个矩阵的所有子矩阵的与和 和 或和. 分析: 或和与是一个东西,只要把所有数都异或上\((1<<31)-1\)然后再从总答案中减掉就能互相转化,考虑求与. 枚举每一位,转化成算有多少个全\(1\)子矩形,单调栈经典问题.总时间复杂度\(\mathrm{O}(n^2\log n)\). 代码: #include <cst…
LOJ#3083. 「GXOI / GZOI2019」与或和 显然是先拆位,AND的答案是所有数字为1的子矩阵的个数 OR是所有的子矩阵个数减去所有数字为0的子矩阵的个数 子矩阵怎么求可以记录每个位置能向上延伸的高度\(h[i][j]\) 枚举左下角的端点,用一个单调栈维护即可 #include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_p…
NOIP2014 提高组模拟试题 第一试试题 题目概况: 中文题目名称 合理种植 排队 科技节 源程序文件名 plant.pas/.c/.cpp lineup.pas/.c/.cpp scifest.pas/.c/.cpp 输入文件名 plant.in lineup.in scifest.in 输出文件名 plant.out lineup.out scifest.out 每个测试点时限 1s 1s 1s 测试点数目 10 10 10 每个测试点分值 10 10 10 内存上限 128MB 128…
题目地址:P5304 [GXOI/GZOI2019]旅行者 这里是官方题解 一个图 \(n\) 点 \(m\) 条边,里面有 \(k\) 个特殊点,问这 \(k\) 个点之间两两最短路的最小值是多少? \(n \leq 10^5, m \leq 5 * 10 ^5\) 假设我们把特殊点分成 \(A,B\) 两个集合,新建 \(s\) 连 \(A\) 集合的所有点,边权 \(0\) ,新建 \(t\) 连接 \(B\) 集合里的所有点,边权 \(0\) ,那么 \(s\) 到 \(t\) 的最短路…
GXOI/GZOI2019题解 P5300 [GXOI/GZOI2019]与或和 一眼题.. 显然枚举每个二进制位,答案就变成了全1子矩阵数量. 这个xjb推推,单调栈一下就行了. #include<bits/stdc++.h> #define il inline #define vd void #define mod 1000000007 typedef long long ll; il ll gi(){ ll x=0,f=1; char ch=getchar(); while(!isdig…
传送门 题目涉及按位与以及按位或运算,所以可以拆位考虑,枚举某个二进制位,然后某个位置如果那个数的第\(i\)位是\(0\)就放\(0\),否则放\(1\),这一位的贡献就是位运算后值为\(1\)的子矩阵个数\(*2^i\).对于与运算,权值为\(1\)的矩阵为全\(1\)矩阵;对于或运算,权值为\(1\)的矩阵为含有\(1\)的矩阵,可以看成是总个数-全\(0\)矩阵个数,然后全\(0\)和全\(1\)矩阵个数可以单调栈求得 #include<bits/stdc++.h> #define L…
题面 思路还是挺容易想的, 只是由于我还是太\(naive\)了一点不会做只会打暴力吧...... 题目要我们求所有子矩阵的\(and\)值之和与\(or\)值之和, 一看之下似乎不好入手, 我们慢慢来. 由于\(and\)和\(or\)运算都是对于每个数的同一位二进制位进行运算的, 所以我们考虑将每个数拆成二进制数, 一位一位地统计答案, 这样的话, 原矩阵就变成了\(log{n}\)个01矩阵, 我们考虑先从\(and\)值入手. 关于\(and\)值 由于是01矩阵, 对于最终答案有贡献的…
最长公共子序列(LCS)问题 你有两个字符串 \(A,B\),字符集为 \(\Sigma\),求 \(A, B\) 的最长公共子序列. 简单动态规划 首先有一个广为人知的 dp:\(f_{i,j}\) 为 \(A\) 的长度为 \(j\) 的前缀与 \(B\) 长度为 \(i\) 的前缀的 LCS.(注意 \(i\) 和 \(j\) 分别对于那个串) 那么显然有: \[f_{i,j} = \begin{cases} f_{i-1, j-1} + 1 & (A_j = B_i) \\ \max(f…
在Java位运算总结-leetcode题目博文中总结了Java提供的按位运算操作符,今天又碰到LeetCode中一道按位操作的题目 Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers in this range, inclusive. For example, given the range [5, 7], you should return 4. 题意:…
一.理解位运算 要学会位运算,首先要清楚什么是位运算?程序中的所有内容在计算机内存中都是以二进制的形式储存的(即:0或1),位运算就是直接对在内存中的二进制数的每位进行运算操作 二.理解数字进制 上面提到了二进制,除了二进制,我们还有很多的进制,下面列举一些常见的进制 10进制数:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 (每位满10进1,同时低位补0)2进制数:00000,00001,00010,00011,00100,00101…
本文目录列表: 1.位运算 2.设置日历数据表节假日标志 3.总结语 4.参考清单列表   位运算   SQL Server支持的按位运算符有三个,分别为:按位与(&).按位或(|).按位异或(^).位运算符用于 int.smallint 或 tinyint 数据,目前SQL Server能支持的按位运算的最大整数类型为Int(4字节整数).有关以上三个按位运算符的详细使用,请参考微软的SQL Server的联机帮助.   设置日期数据表节假日标志   上篇博文(日历数据表详解)中,总结出来一个…
按位运算符是把操作数看作一系列单独的位,而不是一个数字值.所以在这之前,不得不提到什么是"位": 数值或字符在内存内都是被存储为0和 1的序列,每个0和1被称之为1个位,比如说10进制数据2在计算机内被存储为 0 0 0 0 0 0 1 0,当我们将内存内的位值改变之后,这个值代表的意义也就变了,比如把2前移动一位, 现在存储单元里面变成了0 0 0 0 0 1 0 0,这个值表示的是十进制的4,这也就是按位操作符的运算原理. 按位运算符有6个: & 按位与 |按位或 ^按位异…
昨天去面试的时候做到了一道Java的位运算题目,发现有个运算符不懂:">>>",今天特地查了一下,并小结一下常见的位运算符号: ~  按位非(NOT)(一元运算) &  按位与(AND) |  按位或(OR) ^  按位异或(XOR) >>  右移 >>>  右移,左边空出的位以0填充 :无符号右移 <<  左移 &=  按位与赋值 |=  按位或赋值 ^=  按位异或赋值 >>=  右移赋值 &g…
首先每一个权限数都是2的N次方数 如:k1=2 ; //添加 k2=4 ; //删除 k3=8; //修改 ... 如此定义功能权限数,当需要组合权限时,就需要对各个所拥有的权限数按位或了. 如: purview = k2|k3; // 赋给添加和删除权限 当需要判断在权限串中是否拥有某一权限时,就需要进行按位与. 如: if((purview & k1) >0)//判断此权限串是否拥有添加权限,结果>0 则进入if语句代码块中 { .... } 说到这里肯定会有疑问了,别急我来细细讲…
常用的位运算主要有与(&), 或(|)和非(~), 比如: 1 & 0 = 0, 1 | 0 = 1, ~1 = 0 在设计权限时, 我们可以把权限管理操作转换为C#位运算来处理. 第一步, 先建立一个枚举表示所有的权限管理操作: [Flags] public enum Permissions { Insert = , Delete = , Update = , Query = } [Flags]表示该枚举可以支持C#位运算, 而枚举的每一项值, 我们用2的n次方来赋值, 这样表示成二进制…
一 源码.反码.补码 正数的源码.反码.补码相同,例如5:            5的源码:101            5的反码:101            5的补码:101 负数的源码.反码.补码不同,例如-5:            -5的源码:10000101            -5的反码:111111010 (取反操作)            -5的补码:111111011 (补码加1操作) 计算机所有数据都以补码存储和运算. 二 位操作       位操作包含&,|,!分别表示…
程序中的所有数在计算机内存中都是以二进制的形式储存的.位运算直接对整数在内存中的二进制位进行操作.由于位运算直接对内存数据进行操作,不需要转成十进制,因此处理速度非常快. (1),与(&)运算 "&"运算通常用于二进制取位操作,例如一个数 & 1 的结果就是取二进制的最末位.这可以用来判断一个整数的奇偶,二进制的最末位为0表示该数为偶数,最末位为1表示该数为奇数. (2),或(|)运算 "|"运算通常用于二进制特定位上的无条件赋值,例如一个数…
回到目录 我们知道在Linq里的分组groupby可以对集合中一个或者多个字段进行分组,并对其中一个属性进行聚合,而Linq为我们提供了多种聚合方法,由aver,sum,count等,而在大叔权限体系中,以上几种聚合是不够的,因为我们需要对权限字段进行按位聚合,或者说对它进行按位的或运算,这对于学过计算机基础的同学不是什么难事,按位求或,就是将数值先转为二进制,进行两个运算数进行求或,原则是:有1则1,全0才0,这是上学时老师教的,呵呵. 对于Linq的扩展方法微软开发人员都放在了System.…
Java提供的位运算符有:左移( << ).右移( >> ) .无符号右移( >>> ) .位与( & ) .位或( | ).位非( ~ ).位异或( ^ ),除了位非( ~ )是一元操作符外,其它的都是二元操作符. 1.左移( << ) Test1.将5左移2位: package com.xcy; public class Test { public static void main(String[] args) { System.out.p…
最近补充了一些位运算的知识,深感位运算的博大精深,此文作为这个系列的总结篇,在此回顾下所学的位运算知识和应用,同时也补充下前文中没有提到的一些位运算知识. 把一个数变为大于等于该数的最小的2的幂 一个数为2的幂,那么该数的二进制码只有最高位是1. 根据这个性质,我们来举个栗子,比如有数字10,转为二进制码后为: 1 0 1 0 我们只需把 0 bit的位置全部用1填充,然后再把该二进制码加1就ok了.而x | (x + 1)正好可以把最右边的0置为1,可是问题来了,当二进制码变成 1 1 1 1…