[UR#22] 月球列车
一、题目
这种比较精细的题还是要多练练,其实不怎么难但是我看题解都看了三个小时
二、解法
位运算和四则运算混合在一起是很恶心的,方法基本上只有按位考虑。
对于数位 \(w\),我们只需要考虑 \(a_i/x\) 在数位 \(w\) 出现次数的奇偶性,和考虑 \(a_i+x\) 在 \(w-1\) 这个数位上进位次数的奇偶性即可,前者特别容易计算,难点是后者。
一定要记住这种进位问题是有单调性的,我们把 \(a_i\) 按前 \(w-1\) 位从小到大排序后,能产生进位的一定是一段后缀,设 \(V=2^w-x\and(2^w-1)\),进位的充要条件是 \(a_i\and(2^w-1)\geq V\)
如果暴力预处理排序、查询时候暴力二分的话时间复杂度 \(O(n\log n\log a)\)
考虑优化,因为二进制的特性我们可以在排序的时候使用归并排序。查询时候我们想快速得到 \(V\) 在数组上的位置,可以预处理 \(c[w][i][0/1]\) 表示以前第 \(i\) 个位置上的数,考虑第 \(w\) 位之后,不加 \(2^w/\)加上 \(2^w\) 在新数组中的位置。
假设我们知道 \(V\) 以前在数组中的位置,可以通过跳 \(c\) 数组来处理出 \(V\) 在数组中的新位置,这样求出来的是小于等于 \(V\) 的最后一个位置。对于计算答案,如果 \(x\) 这一位为 \(0\) 那么我们找在 \([V,V+2^w)\) 中的数个数,因为 \(a_i\geq V+2^w\) 会因为进位和原本这一位就有值贡献被抵消了;如果 \(x\) 这一位为 \(1\) 那么贡献的数全部取反即可。
时间复杂度 \(O(n\log a)\),真的是道签到题呢
#include <cstdio>
#include <cstring>
const int M = 250005;
#define int long long
int read()
{
int x=0,f=1;char c;
while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
int n,m,t,a[M],c[64][M][2],tmp[M],cur[M];
int work(int x)
{
int cur=n,ans=0;
for(int w=0;w<=60;w++)
{
int cnt=c[w][cur][1]-c[w][cur][0];
if(!((x>>w)&1)) cur=c[w][cur][1];
else cnt=n-cnt,cur=c[w][cur][0];
if(cnt&1) ans|=(1ll<<w);
}
return ans;
}
signed main()
{
n=read();m=read();t=read();
for(int i=1;i<=n;i++)
a[i]=read(),cur[i]=i;
for(int w=0;w<=60;w++)
{
int cnt=0;
c[w][0][0]=cnt;
for(int i=1;i<=n;i++)
{
if(!((a[cur[i]]>>w)&1)) tmp[++cnt]=cur[i];
c[w][i][0]=cnt;
}
c[w][0][1]=cnt;
for(int i=1;i<=n;i++)
{
if((a[cur[i]]>>w)&1) tmp[++cnt]=cur[i];
c[w][i][1]=cnt;
}
memcpy(cur,tmp,sizeof cur);
}
int ans=0;
for(int i=1;i<=m;i++)
{
int x=read();
if(t) x^=(ans>>20);
ans=work(x);
printf("%lld\n",ans);
}
}
原文地址:https://www.cnblogs.com/C202044zxy/p/15375981.html
- 浅析ReDoS的原理与实践
- 使用 Executors,ThreadPoolExecutor,创建线程池,源码分析理解
- CentOS+Nginx+Tomcat搭建高性能负载均衡集群
- Java 四种线程池的使用
- 搭建 Jenkins-2.83 服务,部署 spring boot 项目
- Spring Boot 中使用 Java API 调用 lucene
- Spring Boot 中使用 Java API 调用 Elasticsearch
- Spring Boot 中使用 公共配置
- WebView 和 JS 交互,如何将 Java 对象和 List 传值给 JS ?
- Spring Boot 中使用 LogBack 配置
- Spring Boot 中使用 RabbitMQ
- 手把手教你dubbo怎么用?
- 一步一步实现Android的MVP框架
- Base封装之我的最简MVP架构
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- git禁止在master分支push和commit
- 记录一次mybatis缓存和事务传播行为导致ut挂的排查过程
- appium教程_3.启动appium-server
- appium教程_4.adb常用命令
- Python中的高阶概念属性:五个你应该搞明白的知识点
- 一次奇怪的http状态码改变
- Salesforce LWC学习(二十七) File Upload
- 让我们来谈谈python中的prettyprint和pprint
- vue 开发规范
- Markdown 编写规范
- JavaScript编码规范
- HTML编码规范
- postgres数据库不能用ip地址访问的问题
- Flutter基础widgets教程-ButtonBar篇
- 如何在linux服务上创建samba文件共享服务