当前位置: 首页 > ops >正文

D. Eating【Codeforces Round 1005 (Div. 2)】

D. Eating

题意

n n n 个史莱姆排成一行,第 i i i 个史莱姆的权重为 w i w_i wi。若史莱姆 i i i 的权重满足 w i ≥ w j w_i \geq w_j wiwj,则它可以吃掉史莱姆 j j j;之后,史莱姆 j j j 会消失,史莱姆 i i i 的权重变为 w i ⊕ w j w_i \oplus w_j wiwj ∗ ^{\text{∗}}

史莱姆国王想用参数 x x x 进行以下实验:

• 将一个权重为 x x x 的新史莱姆添加到行的最右端(第 n n n 个史莱姆之后)。

• 这个新史莱姆会尝试吃掉左侧的史莱姆(若满足条件),并移动到被吃者的位置。此过程会持续直到其左侧没有史莱姆,或者左侧史莱姆的权重大于它当前的值。(此过程中其他史莱姆不会被吃掉。)

• 实验的得分为被吃掉的史莱姆总数。

国王会询问 q q q 次查询。每次查询给定整数 x x x,你需要计算该参数下实验的得分。注意这些查询是假设性的,不会实际改变史莱姆的状态(即查询之间相互独立)。

∗ ^{\text{∗}} 此处 ⊕ \oplus 表示按位异或运算。

输入格式

第一行输入整数 t t t ( 1 ≤ t ≤ 1 0 4 1 \le t \le 10^4 1t104),表示测试用例数量。

每个测试用例的第一行包含整数 n n n q q q ( 1 ≤ n , q ≤ 2 ⋅ 1 0 5 1 \le n, q \le 2 \cdot 10^5 1n,q2105),分别表示史莱姆数量和查询次数。

第二行包含 n n n 个整数 w 1 , w 2 , … , w n w_1,w_2,\ldots,w_n w1,w2,,wn ( 1 ≤ w i < 2 30 1 \le w_i < 2^{30} 1wi<230),表示史莱姆的权重。

接下来 q q q 行每行输入一个整数 x x x ( 1 ≤ x < 2 30 1 \le x < 2^{30} 1x<230),表示实验参数。

所有测试用例的 n n n 之和不超过 2 ⋅ 1 0 5 2 \cdot 10^5 2105 q q q 之和不超过 2 ⋅ 1 0 5 2 \cdot 10^5 2105

输出格式

对于每个查询,输出一个整数,表示对应实验的得分。

思路

区间异或和可以用前缀和来快速查询,并且若a的最高有效位大于b,那么a>b。

因此预处理每个位置的二进制信息,利用贪心跳跃加速查询:

  1. 预处理:对每个位置i,记录其二进制位数。维护数组j[i][k],表示在i左侧,二进制位数不超过k的最远位置。这能快速定位可吞吃区间。

  2. 跳跃查询:从右向左处理,每次计算当前x的二进制位数g。利用j[t][g]找到最远可吞吃的位置l,此时区间[l, t]的史莱姆均满足条件。累加数量后,更新x为异或结果,并跳到l-1继续处理。

  3. 复杂度优化:通过预处理,每次查询只需 O ( l o g max ⁡ W ) O(log \max{W}) O(logmaxW)次跳跃,总复杂度 O ( q log ⁡ max ⁡ W ) O(q \log \max{W}) O(qlogmaxW),避免暴力遍历。

通过预处理二进制信息实现快速跳跃,将每次查询的时间从线性优化为对数级。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
#define int long long
#define pb push_back
#define pii pair<int,int>
#define FU(i, a, b) for(int i = (a); i <= (b); ++ i)
#define FD(i, a, b) for(int i = (a); i >= (b); -- i)
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const int maxn= 5e5+5,MAXN = maxn;
int a[200005];
int p[200005];
int j[200005][31];
int rj[31];
int qr(int l,int r){if(l==r)return a[l];return p[r]^p[l-1];
}
void solve() {int n,q;cin>>n>>q;for(int i=1;i<=n;i++){cin>>a[i];p[i]=p[i-1]^a[i];int l= log2(a[i])+1;rj[l]=i;for(int k=1;k<=l;k++)rj[k]=i;for(int k=1;k<=30;k++){j[i][k]=rj[k];}}while(q--){int x,t=n,ans=0;cin>>x;while(x>=a[t] && t>0){int g=log2(x)+1;int l = min(t,j[t][g]+1);x=x^qr(l,t);ans+=t-l+1;t=l-1;}cout<<ans<<" ";}   cout<<endl;
}	signed main() {
#ifdef ONLINE_JUDGE
#elsefreopen("../in.txt", "r", stdin);
#endifcin.tie(0)->ios::sync_with_stdio(0);int T = 1;cin >> T;while (T--) {solve();}return 0;
}	
http://www.xdnf.cn/news/6123.html

相关文章:

  • Spring 中常见的属性注入方式(XML配置文件)
  • 单调栈简单习题分析
  • Web安全核心内容与常见漏洞总结
  • EasyConnect卸载大汇总
  • vulnhub靶场——secarmy
  • 动态多因子策略
  • RDD的自定义分区器
  • stm32 ADC单通道转换
  • 反射, 注解, 动态代理
  • 【PSINS工具箱】基于工具箱的单独GNSS导航、单独INS导航、两者结合组合导航,三种导航的对比程序。附完整的代码
  • 一文理解扩散模型(生成式AI模型)(2)
  • 使用 Docker Desktop 安装 Neo4j 知识图谱
  • VastBase的日常操作记录
  • Qt功能区:简介与安装
  • JS中本地存储(LocalStorage)和会话存储(sessionStorage)的使用和区别
  • vscode - 笔记
  • Deep Learning(手写字识别 - CNN)
  • Python算法思想
  • 企业级IP代理解决方案:负载均衡与API接口集成实践
  • 【导航信号模拟器】【MATLAB APP】MATLAB AppDesigner基本使用教程
  • DA14531如何在固件中生成与时间相关的mac和版本号
  • react+html-docx-js将页面导出为docx
  • 没经过我同意,flink window就把数据存到state里的了?
  • Java 大视界——Java 大数据在智慧交通智能停车诱导系统中的数据融合与实时更新
  • 命令行快速上传文件到SFTP服务器(附参考示例)
  • 灰度图像和RGB图像在数据大小和编码处理方式差别
  • lanqiaoOJ 652:一步之遥 ← 扩展欧几里得定理
  • ESP32-S3R8 使能PSRAM内存
  • 【嵌入式笔记】Modbus TCP
  • 鬼泣:蓄力攻击总结