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 ...
随机推荐
- Linux 使用打印机
前言 在 deepin 上打印机好使,在我的mint上不好使,简单的查看一下deepin上驱动及软件.安装上就行了. 软件及驱动 ii hpijs-ppds 3.18.12+dfsg0-2 all H ...
- MySQL库,表,数据的操作
数据库的操作 1. 创建数据库 create database [if not exists] `数据库名` charset=字符编码(utf8mb4); 如果多次创建会报错 如果不指定字符编码,默认 ...
- Pandas_1_预备知识
Chapter1_Python基础 1.1 Python基础 推导式: 两个对象之间的映射关系,类似于实数之间关系变换的函数,只不过对象变成了矩阵. # Ex1-1 vacabulary = ['co ...
- 【每日一题】【回溯】2021年12月29日-93. 复原 IP 地址
有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔. 例如:"0.1.2.201" 和 "192.1 ...
- go-carbon 1.5.1 版本发布, 修复已知 bug 和新增土耳其翻译文件
carbon 是一个轻量级.语义化.对开发者友好的golang时间处理库,支持链式调用. 目前已被 awesome-go 收录,如果您觉得不错,请给个star吧 github.com/golang-m ...
- 监控Kubernetes集群证书过期时间的三种方案
前言 Kubernetes 中大量用到了证书, 比如 ca证书.以及 kubelet.apiserver.proxy.etcd等组件,还有 kubeconfig 文件. 如果证书过期,轻则无法登录 K ...
- Gradle 使用maven本地仓库 带来的思考
Gradle 使用maven本地仓库 带来的思考 本篇主要探究一下 在使用Gradle 的时候一般会配置 maven 的本地仓库的,那是不是Gradle 可以直接使用 maven本地仓库的jar呢 ? ...
- 软件开发目录规范、python常用内置模块
编程思想的转变 1.面条版阶段 所有的代码全部堆叠在一起.可以看成是直接将所有的数据放在C盘 视频.音频.文本.图片 2.函数版阶段 根据功能的不同封装不同的函数.可以看成是将C盘下的数 ...
- Python简单api实现
flask 作用及简单使用 Flask的简单介绍及使用方法简介_珂鸣玉的博客-CSDN博客_flask 简单api搭建 import flask api = flask.Flask(__name__) ...
- 深入理解IOC并自己实现IOC容器
title: 深入理解IOC并自己实现IOC容器 categories: 后端 tags: - .NET 背景介绍 平时开发的时候我们经常会写出这种代码: var optionA=new A(...) ...