CF 979D Kuro and GCD and XOR and SUM(异或 Trie)
CF 979D Kuro and GCD and XOR and SUM(异或 Trie)
给出q(<=1e5)个操作。操作分两种,一种是插入一个数u(<=1e5),另一种是给出三个数x,k,s(<=1e5),求当前所有u中满足,k|u,x+u<=s,且\(x\oplus u\)最大的u。
做法好神啊。关于异或的问题有一种常见做法,就是利用01trie来查找在一堆数里面,哪个数与x的异或值最大。这道题就是这个思路。如果去掉k必须整除v这个条件,那么就转化成了上一个问题(只不过有最大值的限制,怎么解决具体看代码)。
这道题的做法非常神奇。我们建1e5个Trie,第i个Trie中插入值为i的倍数的数。这样,查询x,k,s时,只要查询第k个Trie即可,因为里面的数一定满足k|v。插入时要遍历u的所有因数si,然后将u插入第si个Trie。
注意,异或运算是在尾部对齐的,但是要在Trie上贪心,所以必须在插入和查询的数前补零,使他们长度相同。
分析一波复杂度:
- 预处理:我们需要预处理出u的因数。u的最大值为Max=1e5。用类似筛法的方法,时间复杂度是\(O(Max(1+\frac{1}{2}+\frac{1}{3}...+\frac{1}{Max}))=O(MaxInMax)\)。
- 查询:就是Trie上的查询,总时间复杂度为\(O(qlog_2Max)\)。
- 插入:一个数最多只有\(log_2(Max)\)个因数(\(2*10^9\)内因数最多的数之一是1837836000,有1536个因数),所以总的时间复杂度为\(O(qlog^2_2(Max))\)。
- 空间复杂度:最多插入\(qlog_2(Max)\)个数,因此空间复杂度为\(qlog_2^2(Max)\)。
果然只能膜拜膜拜。
#include <cstdio>
#include <vector>
using namespace std;
const int maxnum=1e5+5, maxq=1e5+5, maxn=maxq*17*17, INF=1e9;
//maxnum指插入的数的最大值 maxq指查询的最多数目
//maxn指结点的最多数目(=maxq*插入几个trie*插入数的二进制长度)
int s[maxn][2], minm[maxn], v[maxn], tot;
int q, root[maxnum], use[maxnum];
vector<int> div[maxnum];
void init(){
for (int i=1; i<maxnum; ++i)
for (int j=i; j<maxnum; j+=i)
div[j].push_back(i);
}
//把x插到对应的trie里,注意维护子树中的最小数 l:处理到从左到右第几位
void insert(int &now, int x, int l){
if (!now){ now=++tot; minm[now]=INF; }
minm[now]=min(minm[now], x);
if (l==-1){ v[now]+=x; return; }
if ((x>>l)&1) insert(s[now][1], x, l-1);
else insert(s[now][0], x, l-1);
}
//要找到v<=lim,并且x^v尽量大(贪心)。函数返回v
//注意由于没有删除操作,路径底下一定有点。
int query(int now, int x, int lim, int l){ //l:第几位
if (l==-1) return v[now];
int s0=s[now][0], s1=s[now][1];
if (!s0||minm[s0]>lim) return query(s[now][1], x, lim, l-1);
if (!s1||minm[s1]>lim) return query(s[now][0], x, lim, l-1);
if ((x>>l)&1) return query(s[now][0], x, lim, l-1);
else return query(s[now][1], x, lim, l-1);
}
int main(){
init();
scanf("%d", &q); int op, x, k, s;
for (int i=0; i<q; ++i){
scanf("%d", &op);
if (op==1){
scanf("%d", &x);
if (use[x]) continue; use[x]=1;
for (int j=0; j<div[x].size(); ++j)
insert(root[div[x][j]], x, 18);
} else {
scanf("%d%d%d", &x, &k, &s);
if (x%k||!minm[root[k]]||minm[root[k]]+x>s) puts("-1"); //注意可能没有一个数
else printf("%d\n", query(root[k], x, s-x, 18)); //保证一定有解
}
}
return 0;
}
CF 979D Kuro and GCD and XOR and SUM(异或 Trie)的更多相关文章
- Codeforces 979 D. Kuro and GCD and XOR and SUM(异或和,01字典树)
Codeforces 979 D. Kuro and GCD and XOR and SUM 题目大意:有两种操作:①给一个数v,加入数组a中②给出三个数x,k,s:从当前数组a中找出一个数u满足 u ...
- codeforces 979D Kuro and GCD and XOR and SUM
题意: 给出两种操作: 1.添加一个数字x到数组. 2.给出s,x,k,从数组中找出一个数v满足gcd(x,k) % v == 0 && x + v <= s && ...
- CodeForces 979 D Kuro and GCD and XOR and SUM
Kuro and GCD and XOR and SUM 题意:给你一个空数组. 然后有2个操作, 1是往这个数组里面插入某个值, 2.给你一个x, k, s.要求在数组中找到一个v,使得k|gcd( ...
- D. Kuro and GCD and XOR and SUM
Kuro is currently playing an educational game about numbers. The game focuses on the greatest common ...
- CodeForces979D:Kuro and GCD and XOR and SUM(Trie树&指针&Xor)
Kuro is currently playing an educational game about numbers. The game focuses on the greatest common ...
- cf round 482D Kuro and GCD and XOR and SUM
题意: 开始有个空集合,现在有两种操作: $(1,x)$:给集合加一个数$x$,$x \leq 10^5$; $(2,x,k,s)$:在集合中找一个$a$,满足$a \leq s-x$,而且$k|gc ...
- Codeforces Round #482 (Div. 2) : Kuro and GCD and XOR and SUM (寻找最大异或值)
题目链接:http://codeforces.com/contest/979/problem/D 参考大神博客:https://www.cnblogs.com/kickit/p/9046953.htm ...
- cf979d Kuro and GCD and XOR and SUM
set做法 正解是trie-- 主要是要学会 \(a\ \mathrm{xor}\ b \leq a+b\) 这种操作 #include <iostream> #include <c ...
- 【Trie】【枚举约数】Codeforces Round #482 (Div. 2) D. Kuro and GCD and XOR and SUM
题意: 给你一个空的可重集,支持以下操作: 向其中塞进一个数x(不超过100000), 询问(x,K,s):如果K不能整除x,直接输出-1.否则,问你可重集中所有是K的倍数的数之中,小于等于s-x,并 ...
随机推荐
- JavaScript中,让一个div在固定的父div中任意拖动
1.css代码 #big { border: 1px solid #FF3300; width: 300px; height: 300px; position: relative; } #small ...
- spring与mybati整合方法
(1)spring配置文件: <!-- 引入jdbc配置文件 --> <context:property-placeholder location="jdbc.proper ...
- python基础-循环语句for\嵌套循环
for循环格式: for index in range(0,3):#等同于range(3),取0\1\2 print(index) index = 0 starnames = ['xr1','xr2' ...
- 一文读懂所有的编码方式(UTF-8、GBK、Unicode、宽字节...)
编码方式就分两类:ANSI编码.Unicode编码.这两类编码都兼容ASC码. ------------------------------------------------------------ ...
- jspsmartupload 文件上传让input数据和文件上传同时提交
一.使用原因: 文件上传时,表单的属性中必须要有multipart/form-data,如以下例子: <form name="form_post" class="a ...
- PS 滤镜——(扭曲)球面化 Spherize
%%%% Spherize clc; clear all; close all; addpath('E:\PhotoShop Algortihm\Image Processing\PS Algorit ...
- gulp安装简介
1 全局安装gulp:npm install -g gulp 2 在项目根目录中,安装项目的开发依赖:npm install --save-dev gulp 2.1 根据gulpfile.js中的依赖 ...
- Poj 1936,3302 Subsequence(LCS)
一.Description(3302) Given a string s of length n, a subsequence of it, is defined as another string ...
- 【转】js中select的基本操作
判断select选项中 是否存在Value="paraValue"的Item // 1.判断select选项中 是否存在Value="paraValue"的I ...
- 使用变参函数实现pwd命令
#include "stdafx.h"#include <Windows.h> #define DIRNAME_LEN (MAX_PATH+2) BOOL PrintS ...