牛客练习赛81 B. 小 Q 与彼岸花(DP/Trie/树状数组/FWT/好题)
链接:https://ac.nowcoder.com/acm/contest/11171/B
来源:牛客网
小 Q 的院子里种了 n朵彼岸花,其中第 i 朵的彼岸花的美丽值为 ai,彼岸花按照编号从小到大从左向右排成了一排。
现在小 Q 有 m 个问题,他每次会给出一个区间 [l,r][l,r],他想在编号属于区间 [l,r][l,r] 的彼岸花中选出两朵花,使得 ai⨁aj(⨁ 表示按位异或操作) 的值最大(如果只能选出一朵花请直接输出 0)。
由于他太菜了,只能来问你了。
输入描述:
第一行两个整数 n,m(1≤n,m≤5×103)。
第二行 n 个整数,分别表示 a1,a2,...,an(1≤ai≤210)。
接下来 m 行,每行两个整数分别表示一个问题所给出的区间 l,r(1≤l≤r≤n)。
输出描述:
输出 m 行,表示每个问题的答案。
示例1
输入
复制
10 10
1 2 3 4 5 6 7 8 9 10
1 2
1 3
1 5
2 6
2 8
2 10
3 7
8 10
6 9
1 7
输出
复制
3
3
7
7
15
15
7
3
15
7
最简单的还是DP,可以解决静态查找区间最值的问题。设dp[i, j]表示i到j区间任取两个数能够异或出来的最大值,初始化dp[i, j] = a[i] ^ a[j],有转移方程:。即i到j的能够异或出来的最大值可能从i到j - 1,i + 1到j以及a[i]^a[j]中取得。注意遍历的顺序。
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, m;
long long a[5005], dp[5005][5005];
#define ll long long
signed main() {
cin >> n >> m;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++) {
dp[i][i] = a[i];
for(int j = 1; j <= n; j++) {
dp[i][j] = a[i] ^ a[j];
}
}
for(int i = n; i >= 1; i--) {
for(int j = i + 1; j <= n; j++) {
dp[i][j] = max(dp[i][j], max(dp[i][j - 1], dp[i + 1][j]));
}
}
for(int i = 1; i <= m; i++) {
int l, r;
cin >> l >> r;
if(l == r) cout << 0 << endl;
else {
cout << dp[l][r] << endl;
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!