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

题解:uoj703 赵云八卦阵

题意:给出一个序列 \(a\),每次可以将一项 \(a_i\) 变成 \(a_i\oplus a_{i-1}\),问 \(a\) 序列的最长上升子序列最大为多少。\(n\le 10^6,V< 2^{60}\)

做法:

首先稍微手玩一下会发现 \(a_i\) 可以随意异或上前面的任意一个数,这个从前往后推一下就行。同时考虑从后往前满足每一个数,所以每个数选什么是独立的。

那么就是考虑每个数可以变成 \(a_i\) 任意异或上前面的数,异或出来的序列上升子序列最大长度。

既然是随意异或上前面每个数,那么我们可以先对每个前缀求一个线性基。为了方便,我们先把所有的基去消个元,这样就可以用一个二进制数去对应一个实际的数,并且这两个的大小关系是完全一样的,就比较方便我们去比较。

考虑有两种求上升子序列的做法,一种是直接枚举第 \(i\) 个然后对前面取 \(\max\),但是有个问题是我每个位置取值是很多的,直接枚举爆炸完了。所以我们采用另一种做法,考虑 \(dp_i\) 代表长为 \(i\) 的上升序列末尾最小值为多少。

对两类情况分别讨论,假设目前线性基大小为 \(k\),一种是我 \(a_i\) 加入线性基之后不改变线性基,那么很显然 \([0,2^k)\) 都是可以凑出来的,转移为 \(f_{i}\leftarrow f_{i-1}+1\)。我们可以把连续线性基大小都为 \(k\) 的一起做,转移改为 \(f_{i}\leftarrow f_{i-k}+k\)。但是要注意,不能大于等于 \(2^k\),因为填不了这么大。

那么考虑第二种,改变线性基的情况,这种情况只有 \(O(\log V)\) 种,所以我们可以接受 \(O(n)\) 的处理。我们先把 \(dp\) 值更新成加入这个数之后的状态,具体可以见代码。然后考虑 \(dp_i\) 怎么贡献,那就是找到 \(dp_i\) 后第一个比 \(dp_i\) 大且包含我新加入的这一位的元素即可。

剩下就是一些代码层面上的东西,可以看代码理解一下具体的过程。

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1e6 + 5;
int n, a[maxn];
struct Base {int d[61];pair<int, int> ins(int x) {int msk = 0;for (int i = 60; i >= 0; i--) {if((x >> i) & 1) {if(!d[i]) {d[i] = x;for (int j = i - 1; j >= 0; j--)if(d[j] && ((d[i] >> j) & 1))d[i] ^= d[j];for (int j = 60; j >= i + 1; j--) {if(d[j]) {msk <<= 1;if((d[j] >> i) & 1)d[j] ^= d[i], msk |= 1;}}msk <<= 1;return make_pair(i, msk);}x ^= d[i];}}return make_pair(-1, 0);}
} Tree;
int dp[maxn], len, mx;
void shift(int x) {len += x;for (int i = len; i > x; i--)dp[i] = dp[i - x] + x;for (int j = 1; j <= x; j++)dp[j] = j - 1;while(dp[len] >= (1ll << mx))len--;
}
int cal(int x) {int cnt = 0;while(x)cnt ^= x & 1, x >>= 1;return cnt;
}
signed main() {ios::sync_with_stdio(false);cin >> n;for (int i = 1; i <= n; i++)cin >> a[i];int lst = 0;for (int i = 1; i <= n; i++) {//	cout << Tree.d[0] << endl;pair<int, int> mp = Tree.ins(a[i]);if(mp.first == -1) {lst++;continue;}shift(lst), lst = 0;mx++;int ct = 0;for (int j = 0; j < mp.first; j++)ct += (Tree.d[j] > 0);int nw = mp.second; nw |= 1; nw <<= ct;for (int j = 1; j <= len; j++) {dp[j] += (dp[j] >> ct) << ct;if(cal(nw & dp[j]))dp[j] |= (1ll << ct);}//	cout << nw << " asdf" << cal(1 & nw) << " " << ct << " " << mp.first << endl;for (int j = len; j >= 0; j--) {int val = dp[j] + 1;//	cout << val << " " << (nw & val) << " " << j << " " << nw << endl;while(!cal(nw & val))val = ((val >> ct) + 1) << ct;if(val >= (1ll << mx))continue;if(j == len)dp[++len] = 9e18;dp[j + 1] = min(dp[j + 1], val);}
//		for (int j = 0; j <= len; j++)
//			cout << dp[j] << " ";
//		cout << endl;}shift(lst);cout << len << endl;return 0;
}
http://www.zskr.cn/news/38608.html

相关文章:

  • 2025年鸡蛋剥壳线定制厂家权威推荐榜单:鸡蛋蒸煮剥壳线/鸡蛋剥壳设备/鸡蛋清洗烘干流水线源头厂家精选
  • 2025年郑州地区大巴车租赁品牌机构推荐:五大专业大巴车租赁公司权威测评
  • 2025年市场上小程序开发公司口碑排行榜单:揭秘顶级服务商与选择技巧
  • 基于W5500芯片实现DHCP自动获取IP功能
  • 2025年公交站牌厂家推荐:智能交通设施的未来趋势与选择指南
  • 2025 年粘合剂厂家最新推荐榜:品牌权威甄选及选择指南型煤复合/污泥球团/矿粉球团/矿粉粘合剂公司推荐
  • 基础排序算法(七)归并排序
  • 2025年11月公交站台生产厂家推荐榜:揭秘顶级公交站台生产厂家江苏兰太的成功秘诀
  • 2025 年半导体晶片生产厂家最新推荐榜单:专利技术与规模化供货能力深度解析及选购指南
  • 2025年11月机器人线束生产厂家推荐前十榜单:东莞众晟强电子领跑行业
  • 使用pyqt5 pyserial TTS模型vosk开发的语音串口工具
  • 十分钟读懂 Deepseek MTP(Multi-Token Prediction)
  • 适合高中数学辅导的培训机构怎么选?从基础到拔高这样挑不踩坑
  • pcb入门
  • 6.AUserDefaults 使用指南
  • S-PSC 5202 游记
  • 2025年11月全屋定制品牌推荐评价:消费者满意度调查结果
  • 2025年11月全屋定制品牌推荐榜单:十大品牌综合对比与权威评测
  • 2025年10月深圳律师推荐榜:五家刑事辩护团队对比与中立评测
  • 2025年11月法律咨询律所推荐排名:用户需求匹配度全解析
  • 2025年11月市场地位认证机构排行解析:专业认证服务深度评测
  • 2025年项目管理软件排行榜前五!从需求到交付你怎么选? - RAIN
  • 学习一下压测和监控
  • 2025年11月办公家具公司推荐榜单:权威评测与综合对比分析
  • 2025年11月领先品牌认证机构排行榜:权威评测与选择指南
  • WinMTR Json版:支持 JSON 配置的内网路径追踪工具
  • 2025年11月遗嘱继承律所评价:多维数据与行业标准解析
  • Python 文件操作
  • 谭剑波day10
  • tp8-商城项目 命令合集