感想

这道题还算良心,有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 线性基的更多相关文章

  1. NOI模拟赛 Day1

    [考完试不想说话系列] 他们都会做呢QAQ 我毛线也不会呢QAQ 悲伤ING 考试问题: 1.感觉不是很清醒,有点困╯﹏╰ 2.为啥总不按照计划来!!! 3.脑洞在哪里 4.把模拟赛当作真正的比赛,紧 ...

  2. 6.28 NOI模拟赛 好题 状压dp 随机化

    算是一道比较新颖的题目 尽管好像是两年前的省选模拟赛题目.. 对于20%的分数 可以进行爆搜,对于另外20%的数据 因为k很小所以考虑上状压dp. 观察最后答案是一个连通块 从而可以发现这个连通块必然 ...

  3. NOI 模拟赛 #2

    得分非常惨惨,半个小时写的纯暴力 70 分竟然拿了 rank 1... 如果 OYJason 和 wxjor 在可能会被爆踩吧 嘤 T1 欧拉子图 给一个无向图,如果一个边集的导出子图是一个欧拉回路, ...

  4. 【2018.12.10】NOI模拟赛3

    题目 WZJ题解 大概就是全场就我写不过 $FFT$ 系列吧……自闭 T1 奶一口,下次再写不出这种 $NTT$ 裸题题目我就艹了自己 -_-||| 而且这跟我口胡的自创模拟题 $set1$ 的 $T ...

  5. 7.11 NOI模拟赛 qiqi20021026的T1 四个指针莫队 trie树

    LINK:qiqi20021026的T1 考场上只拿到了50分的\(nq\)暴力. 考虑一个区间和一个区间配对怎么做 二分图最大带权匹配复杂度太高. 先考虑LCS的问题 常见解决方法是后缀数组/tri ...

  6. 7.12 NOI模拟赛 积性函数求和 数论基础变换 莫比乌斯反演

    神题! 一眼powerful number 复习了一下+推半天. 可以发现G函数只能为\(\sum_{d}[d|x]d\) 不断的推 可以发现最后需要求很多块G函数的前缀和 发现只有\(\sqrt(n ...

  7. 7.1 NOI模拟赛 dp floyd

    这是一道非常垃圾的题目 且 数据范围简直迷惑选手.. 可以发现 题目中有 边权递增 边的条数 所有边权值不同 最小边权和等条件. 看起来很难做 一个想法 边权递增+边的1的权值都不相同可以想到 关系存 ...

  8. NOI模拟赛Day5

    T1 有and,xor,or三种操作,每个人手中一个数,求和左边进行某一种运算的最大值,当t==2时,还需要求最大值的个数. test1 20% n<=1000 O(n^2)暴力 test2 2 ...

  9. NOI模拟赛Day4

    看到成绩的时候我的内心** woc第一题写错了呵呵呵呵呵呵呵呵 人不能太浪,会遭报应的** ------------------------------------------------------ ...

  10. NOI模拟赛Day3

    终于A题啦鼓掌~开心~ 开考看完题后,觉得第二题很好捏(傻叉上线 搞到十一点准备弃疗了然后突然发现我会做第一题 于是瞎码了码,就去准备饭票了... 好了,停止扯淡(就我一个我妹子每天不说话好难受QAQ ...

随机推荐

  1. Proxmox VE安装CentOS 8.3

    相信玩服务器/VPS的对CentOS一定不陌生,CentOS 是一个基于Red Hat Linux 提供的可自由使用源代码的企业级Linux发行版本.因为是免费的,现在很多WEB服务器和VPS都经常使 ...

  2. Oracle 修改SYS、system用户密码

      by:授客 QQ:1033553122 概念 SYS用户是Oracle中权限最高的用户,而SYSTEM是一个用于数据库管理的用户.在数据库安装完之后,应立即修改SYS,SYSTEM这两个用户的密码 ...

  3. Ubuntu截屏工具推荐

    Ubuntu截屏工具推荐 本篇博文推荐Ubuntu下的截屏工具Flameshot,可以作为Windows下Snipaste截图工具的平替. GitHub地址:https://github.com/fl ...

  4. BUUCTF---keyboard

    题目 ooo yyy ii w uuu ee uuuu yyy uuuu y w uuu i i rr w i i rr rrr uuuu rrr uuuu t ii uuuu i w u rrr e ...

  5. RL · Exploration | 使用时序距离构造 intrinsic reward,鼓励 agent 探索

    论文标题:Episodic Novelty Through Temporal Distance. ICLR 2025,8 8 6 5 poster. arxiv:https://arxiv.org/a ...

  6. 一个开源的 Blazor 跨平台入门级实战项目

    前言 今天大姚给大家分享一个开源(MIT license).免费的 Blazor 跨平台入门级实战项目:YourWeather. 项目介绍 YourWeather是一个开源(MIT license). ...

  7. 36条技巧优化PHP代码(总结)

    原文:38条技巧优化PHP代码 1.如果一个方法能被静态,那就声明他为静态的,速度可提高1/4; 2.echo的效率高于print,因为echo没有返回值,print返回一个整型; 3.在循环之前设置 ...

  8. wget--批量下载

    wget--批量下载 wget -nd -r -l1 --no-parent --accept=jar http://192.168.38.38:81/js/jartest/ -nd 不创建目录, w ...

  9. 【经验】you-get + ffmpeg|b站音频下载

    一.原理: you-get下载,ffmpeg音视频分离. 这两个都是命令行工具. you-get安装(无python环境请参考python详细安装教程): pip3 install --upgrade ...

  10. 点赞背后的技术大冒险:分布式事务与SAGA模式

    title: 点赞背后的技术大冒险:分布式事务与SAGA模式 date: 2025/05/07 00:12:40 updated: 2025/05/07 00:12:40 author: cmdrag ...