校内NOI模拟赛006T1 签到sign 线性基
感想
这道题还算良心,有30pts的暴力……但是这次模拟赛又双叒叕是勒堕赛制,而且试题的标题居然还是NOI模拟测试!打暴力的时候我也没有想到我可以现学现卖一个线性基呢...
数据又是脚造的(
虽然标题时模拟赛,但是这里我主要是想讲线性基而不是这道题。
例题
【问题描述】
有一个 × 的网格,第行第列的格子我们记作(,)。每个格子上都有一个数字,(,)上的数字为,。 你现在在(1,1),你想走到(, )处签到,每次你可以走到上下左右四个相邻的格子中的一个,当然,你不能走出网格。
你现在的心情值为1,1,你的心情飘忽不定,你每走一步,你的心情值就会异或上走到的格子上的数字。
你希望你签到的时候心情最好,为此你可以任意绕远路,甚至可以走到签到处的时候暂时不签到。
请你求出最大的心情值。
【输入格式】
第一行两个正整数, 。
接下来行,每行个非负整数,其中第行第个整数表示,。
【输出格式】
输出一个整数,表示答案。
【样例输入】
2 2
1 2
3 4
【样例输出】
7
【数据范围】
对于 30%的数据,, ≤ 4。
另有 30%的数据,, ≤ 100,, ≤ 1000。
对于 100%的数据,, ≤ 500,, ≤ 109。
分析
转化题意:
求一条路径(可以随便乱走,只规定起点和终点),使路径上所有数的xor max
看到这类xor问题,首先想到了线性基!线性基最适合解决这类xor问题了!
稍稍分析一下,结合xor的性质:
- ABB=A
- if A^B=C then A^C=B & B^C=A
- ...
发现,对于一个点如果我们走了两次,那么就相当于那个点没有被选
所以对于一个点可以任意决定它是否被选
但是又因为要从起点出发,终点停下,易得那么一共要走的步数的奇偶性与n+m-1相同
也就是说,需要保证从线性基中取出的xor max这个数一定要保证是被奇/偶数个数字xor得到的
那么怎么办呢?
answer:利用线性基的贪心,插入的时候把每个数的第30(不一定要30,只要够高就行)位赋为1,这样取出来的数字一定会保证是奇数个(如果是偶数个,230就会被xor消失了),再将贪心初值赋值为0(如果需要奇数个)或230(需要偶数个数的xor)
如果初值是0,那么从高位开始贪心时,2^30一定会被选择(为1),从而保证取出的数一定是奇数个
如果初值是230,那么从高位开始贪心时,230一定要是0,保证了取出的数一定是偶数个
最后输出的时候别忘记减去2^30
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#define IL inline
#define re register
#define LL long long
#define ULL unsigned long long
#define re register
#define debug printf("Now is %d\n",__LINE__);
using namespace std;
int n,m,ans;
ULL a[600][600];
ULL p[63];
void insert(ULL x)
{
for(int i=62;i>=0;i--)
{
if((x>>i)&1)
{
if(p[i]==0)
{
p[i]=x;
break;
}
else
{
x^=p[i];
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
insert(a[i][j]+(1<<30));
}
}
ULL ans=((n+m-1)&1?(0):(1<<30));
for(int i=62;i>=0;i--)
{
if((ans^p[i])>ans) ans^=p[i];
}
cout<<ans-(1<<30);
return 0;
}
当然,你可能 还不知道线性基是什么……没事,我也刚刚才弄懂。
线性基
接下来详细的讲一下线性基是什么
定义
线性基是一种擅长处理异或问题的数据结构
有一个正整数集A,线性基P;
设值域为[1,N],就可以用一个长度为logN的数组来描述一个线性基。
特别地,线性基第i位上的数二进制下最高位也为第i位。
一个线性基满足,对于它所表示的所有数的集合A,A中任意多个数异或所得的结果均能表示为线性基中的元素互相异或的结果,即意,线性基能使用异或运算来表示原数集使用异或运算能表示的所有数。运用这个性质,我们可以极大地缩小异或操作所需的查询次数。
构造(插入)
一开始线性基为空
对于要插入的每一个数,从高位开始判断;
设当前为x的二进制的最高位i(这里是指最高为1的位)
- 若线性基第i位为0,则直接插入(赋值)并退出
- 否则x=x^p[i],重复以上操作直到x==0
void insert(ULL x)
{
for(int i=62;i>=0;i--)
{
if((x>>i)&1)
{
if(p[i]==0)
{
p[i]=x;
break;
}
else
{
x^=p[i];
}
}
}
}
判断
判断一个数x是否能被这个线性基表示出来
判断和插入类似
如果判断退出时,x==0,则说明此时线性基已经可以表示x了,否则说明为了插入x,线性基插入了一个新元素
bool judge(ULL x)
{
for(int i=62;i>=0;i--)
{
if((x>>i)&1)
{
if(p[i]==0)
{
return 0;
}
else
{
x^=p[i];
}
}
}
return 1;
}
查询最大值
基于贪心,我们从高到低地扫描线性基。直接比较取max即可。
ULL ans=0;
for(int i=62;i>=0;i--)
{
if((ans^p[i])>ans) ans^=p[i];
}
显然每次ans不会变劣,所以最后的ans就是答案。
当然,还可以给ans的初值不为0
这样,查询的就是max(ans^线性基能表达的数)了
查询最小值
首先要特判是否能表达0
再根据线性基查询最大值时的贪心一样,从低位开始扫描即可。
当然这次不需要扫完,只要p[i]有数据,返回即可。因为从低位开始扫的话,越xor就会越大。
if(flag) return 0;
for(int i=0;i<=62;i++)
if(p[i]) return p[i];
校内NOI模拟赛006T1 签到sign 线性基的更多相关文章
- NOI模拟赛 Day1
[考完试不想说话系列] 他们都会做呢QAQ 我毛线也不会呢QAQ 悲伤ING 考试问题: 1.感觉不是很清醒,有点困╯﹏╰ 2.为啥总不按照计划来!!! 3.脑洞在哪里 4.把模拟赛当作真正的比赛,紧 ...
- 6.28 NOI模拟赛 好题 状压dp 随机化
算是一道比较新颖的题目 尽管好像是两年前的省选模拟赛题目.. 对于20%的分数 可以进行爆搜,对于另外20%的数据 因为k很小所以考虑上状压dp. 观察最后答案是一个连通块 从而可以发现这个连通块必然 ...
- NOI 模拟赛 #2
得分非常惨惨,半个小时写的纯暴力 70 分竟然拿了 rank 1... 如果 OYJason 和 wxjor 在可能会被爆踩吧 嘤 T1 欧拉子图 给一个无向图,如果一个边集的导出子图是一个欧拉回路, ...
- 【2018.12.10】NOI模拟赛3
题目 WZJ题解 大概就是全场就我写不过 $FFT$ 系列吧……自闭 T1 奶一口,下次再写不出这种 $NTT$ 裸题题目我就艹了自己 -_-||| 而且这跟我口胡的自创模拟题 $set1$ 的 $T ...
- 7.11 NOI模拟赛 qiqi20021026的T1 四个指针莫队 trie树
LINK:qiqi20021026的T1 考场上只拿到了50分的\(nq\)暴力. 考虑一个区间和一个区间配对怎么做 二分图最大带权匹配复杂度太高. 先考虑LCS的问题 常见解决方法是后缀数组/tri ...
- 7.12 NOI模拟赛 积性函数求和 数论基础变换 莫比乌斯反演
神题! 一眼powerful number 复习了一下+推半天. 可以发现G函数只能为\(\sum_{d}[d|x]d\) 不断的推 可以发现最后需要求很多块G函数的前缀和 发现只有\(\sqrt(n ...
- 7.1 NOI模拟赛 dp floyd
这是一道非常垃圾的题目 且 数据范围简直迷惑选手.. 可以发现 题目中有 边权递增 边的条数 所有边权值不同 最小边权和等条件. 看起来很难做 一个想法 边权递增+边的1的权值都不相同可以想到 关系存 ...
- NOI模拟赛Day5
T1 有and,xor,or三种操作,每个人手中一个数,求和左边进行某一种运算的最大值,当t==2时,还需要求最大值的个数. test1 20% n<=1000 O(n^2)暴力 test2 2 ...
- NOI模拟赛Day4
看到成绩的时候我的内心** woc第一题写错了呵呵呵呵呵呵呵呵 人不能太浪,会遭报应的** ------------------------------------------------------ ...
- NOI模拟赛Day3
终于A题啦鼓掌~开心~ 开考看完题后,觉得第二题很好捏(傻叉上线 搞到十一点准备弃疗了然后突然发现我会做第一题 于是瞎码了码,就去准备饭票了... 好了,停止扯淡(就我一个我妹子每天不说话好难受QAQ ...
随机推荐
- Oracle 23ai TPC-H 测试环境部署
最近,我在 Oracle Database 23ai 上进行了 TPC-H 100GB 测试,并整理了完整的实施步骤和优化经验.如果你也想评估 Oracle 数据库在决策支持场景下的性能,可以参考我的 ...
- Manus爆火,是硬核还是营销?
相信这两天小伙伴们应该被Manus刷屏了,铺天盖地的体验解读文章接踵而来,比如「数字生命卡兹克」凌晨爆肝的热文:「一手体验首款通用Agent产品Manus」.从公众号.朋友圈.抖音.央媒,都能看到Ma ...
- 基于Element的el-input实现一个可以显示千分位符的金额输入框
直接上代码 1 <template> 2 <!-- 定义一个 Element UI 的输入框组件 --> 3 <el-input 4 v-model="form ...
- golang实现三重DES加密解密
DES DES(Data Encryption)是1977年美国联邦信息处理标准(FIPS)中所采用的一种对称密码(FIPS46-3),一直以来被美国及其他国家的政府和银行等广泛使用.随着计算机的进步 ...
- go 判断数组下标是否存在
举例 现在需要判断命令行是否传了参数,即 os.Args[1] 是否存在 如果使用下述的判断: func main() { fmt.Println(os.Args[1]) } 会报错:index ou ...
- Arrays工具类--java进阶day06
1.Arrays工具类 这些方法都是针对数组,并且都被static修饰,可以直接使用类名进行调用 1.toString 将数组拼接成带有相对应格式的字符串,可用于展示数组 2.equals 比较两个数 ...
- 学习Kotlin语法(一)
简介 Kotlin是一种现代.简洁且功能强大的编程语言,特别适合Android开发.本文将从基础语法开始,逐步掌握Kotlin的核心特性. 目录 变量 基本类型 数字 无符号对应项 布尔值 字符和字符 ...
- AI时代:本地运行大模型vllm
https://docs.vllm.ai/en/latest/index.html 高吞吐量.高内存效率的 LLMs 推理和服务引擎(快速搭建本地大模型,且openAI API 兼容) vLLM is ...
- 正反代理-nginx安装
参考文章:https://www.cnblogs.com/ysocean/p/9384877.html 先预祝一下成功 废话不多说,开始吧,步骤不多 下载地址 https://nginx.org/en ...
- 记录 Windows关闭自动更新