CF1625D.Binary Spiders
\(\text{Problem}\)
大概就是给出 \(n\) 个数和 \(m\),要从中选最多的数使得两两异或值大于等于 \(m\)
输出方案
\(\text{Solution}\)
一开始的想法很复杂、、、
其实用到一个结论就做好了
对于一个升序数列,它们两两间的异或最小值就是相邻数的异或最小值
于是可以先排序,再 \(DP\)
设 \(f_i\) 表示到第 \(i\) 位强制选 \(i\) 能选出最多的数的数量
那么 \(f_i = f_{j} + 1(1\le j < i,a_j \oplus a_i \ge m)\)
于是优化这个 \(O(n^2)\) 的 \(DP\) 即可
这就是个很简单的事
考虑 \(j\) 的选取
若 \(a_i \oplus a_j > m\),那么异或值从高位到低位一部分等于 \(m\),然后在某一位大于 \(m\)
那么我们从高到低枚举位数,考虑在这一位之前等于 \(m\),统计这一位大于 \(m\) 的贡献
讨论 \(m\) 和 \(a_i\) 这一位的 \(0/1\) 值,发现可行数值区间是连续的,权值线段树即可
最后再处理 \(a_i \oplus a_j = m\) 的贡献
\(\text{Code}\)
#include <cstdio>
#include <iostream>
#include <algorithm>
#define RE register
#define IN inline
using namespace std;
typedef long long LL;
const int N = 3e5 + 5;
int n, m, f[N], g[N], Len, size, rt;
struct node{int v, id;}a[N];
IN bool cmp(node a, node b){return a.v < b.v;}
int seg[N * 31], ls[N * 31], rs[N * 31];
void Modify(int &p, int l, int r, int x, int v)
{
if (!p) p = ++size;
if (l == r) return seg[p] = v, void();
int mid = l + r >> 1;
if (x <= mid) Modify(ls[p], l, mid, x, v);
else Modify(rs[p], mid + 1, r, x, v);
if (f[seg[ls[p]]] > f[seg[rs[p]]]) seg[p] = seg[ls[p]];
else seg[p] = seg[rs[p]];
}
int Query(int p, int l, int r, int x, int y)
{
if (x > r || y < l) return 0;
if (x <= l && r <= y) return seg[p];
int mid = l + r >> 1, L = 0, R = 0;
if (ls[p] && x <= mid) L = Query(ls[p], l, mid, x, y);
if (rs[p] && y > mid)
{
R = Query(rs[p], mid + 1, r, x, y);
if (!L) L = R;
else{
if (f[L] > f[R]) return L;
return R;
}
}
return L;
}
int main()
{
scanf("%d%d", &n, &m);
for(RE int i = 1; i <= n; i++) scanf("%d", &a[i].v), a[i].id = i;
sort(a + 1, a + n + 1, cmp), Len = a[n].v;
int ans = 1, pos = 0, pre, cur;
for(RE int i = 1; i <= n; i++)
{
f[i] = 1, pre = 0;
for(RE int j = 30; j >= 0; j--)
{
if ((m >> j) & 1){if (!((a[i].v >> j) & 1)) pre |= (1 << j);}
else{
if ((a[i].v >> j) & 1)
{
cur = Query(rt, 0, Len, pre, pre + (1 << j) - 1), pre |= (1 << j);
if (f[cur] + 1 > f[i]) f[i] = f[cur] + 1, g[i] = cur;
}
else{
cur = Query(rt, 0, Len, pre + (1 << j), (LL)pre + (1LL << j + 1) - 1);
if (f[cur] + 1 > f[i]) f[i] = f[cur] + 1, g[i] = cur;
}
}
if (!j)
{
cur = Query(rt, 0, Len, pre, pre);
if (f[cur] + 1 > f[i]) f[i] = f[cur] + 1, g[i] = cur;
}
}
if (ans < f[i]) ans = f[i], pos = i;
if (i < n) Modify(rt, 0, Len, a[i].v, i);
}
printf("%d\n", (ans == 1) ? -1 : ans);
if (ans > 1) while (pos) printf("%d ", a[pos].id), pos = g[pos];
}
CF1625D.Binary Spiders的更多相关文章
- CF1625D - Binary Spiders[trie树优化dp]
官方题解 题意:给数列a[],选择尽量多的数满足任意两个异或起来<=k 1625D - Binary Spiders 思路:首先,将数列排序得到,然后升序取得的值的任意两个最小值为相邻两个异或的 ...
- [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法
二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...
- ILJMALL project过程中遇到Fragment嵌套问题:IllegalArgumentException: Binary XML file line #23: Duplicate id
出现场景:当点击"分类"再返回"首页"时,发生error退出 BUG描述:Caused by: java.lang.IllegalArgumentExcep ...
- Leetcode 笔记 110 - Balanced Binary Tree
题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...
- Leetcode 笔记 99 - Recover Binary Search Tree
题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...
- Leetcode 笔记 98 - Validate Binary Search Tree
题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...
- Leetcode: Convert sorted list to binary search tree (No. 109)
Sept. 22, 2015 学一道算法题, 经常回顾一下. 第二次重温, 决定增加一些图片, 帮助自己记忆. 在网上找他人的资料, 不如自己动手. 把从底向上树的算法搞通俗一些. 先做一个例子: 9 ...
- Leetcode, construct binary tree from inorder and post order traversal
Sept. 13, 2015 Spent more than a few hours to work on the leetcode problem, and my favorite blogs ab ...
- [LeetCode] Binary Watch 二进制表
A binary watch has 4 LEDs on the top which represent the hours (0-11), and the 6 LEDs on the bottom ...
- [LeetCode] Find Leaves of Binary Tree 找二叉树的叶节点
Given a binary tree, find all leaves and then remove those leaves. Then repeat the previous steps un ...
随机推荐
- 求10以内所有偶数和-Java
public class Demo{ //求10以内所有偶数和 public static void main (String[] args){ int sum = 0; for(int i = 0; ...
- Python编程规范之PEP8
Python编程规范-PEP8 PEP是 Python Enhancement Proposal 的缩写. 英文链接: https://legacy.python.org/dev/peps/pep-0 ...
- L1-050 倒数第N个字符串 (15分)
L1-050 倒数第N个字符串 (15分) 给定一个完全由小写英文字母组成的字符串等差递增序列,该序列中的每个字符串的长度固定为 L,从 L 个 a 开始,以 1 为步长递增.例如当 L 为 3 时, ...
- 静态文件配置 django连接MySQL django模型层初识 ORM基本语句
目录 静态文件配置 1. 问题描述 2. 静态文件 3. 资源访问 form表单属性补充 action method 请求方法 get请求 post请求 views层 request对象 reques ...
- Django三大主流Web框架(django版本安装-项目创建-应用创建-django三板斧)
目录 一:python三大主流web框架 1.python三大主流Web框架 2:三大主流web框架特点 二:正常运行Django项目所需要知道的注意事项 1.计算机的名称不能有中文,不然bug在哪你 ...
- jQuery基本使用
目录 一:jQuery查找标签 1.基本选择器 二:分组与嵌套 三:组合选择器 四:jQuery基本筛选器 五:属性选择器 1.属性标签 六:JQuery表单筛选器 1.type属性 2.表单对象属性 ...
- MYSQL进阶学习笔记
MySQL在Linux中的使用: 1.查看mysql在linux的安装版本 mysqladmin –version 2.mysql服务的启动与停止 (1).启动: service mysql star ...
- 学习.NET MAUI Blazor(三)、创建.NET MAUI Blazor应用并使用AntDesignBlazor
大致了解了Blazor和MAUI之后,尝试创建一个.NET MAUI Blazor应用. 需要注意的是: 虽然都叫MAUI,但.NET MAUI与.NET MAUI Blazor 并不相同,MAUI还 ...
- 重新捋一捋React源码之更新渲染流程
前言 前些天在看Dan Abramov个人博客(推荐阅读,站在React开发者的角度去解读一些API的设计初衷和最佳实践)里的一篇文章,其重点部分的思想就是即使不使用Memo(),也可以通过组合的方式 ...
- C++获取含有中文字符的string长度
:前言 造车轮的时候要用到中文字符串的长度辨别,发现char的识别不准,进行了一番研究. > 开始研究 在Windows下,中文字符在C++中的内存占用为2字节,此时采用字符串长度获取函数得到的 ...