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,并 ... 
随机推荐
- NET 平台下的WebService 简单使用
			一句话理解:提供可供外部访问的方法,实现跨平台访问 注意: 在客户端是添加“服务引用”,而不是引用 当服务端更新了服务之后,在客户端,一定也要“更新服务” 当要执行异常调用时,要在前台.aspx的头部 ... 
- Oracle使用hs odbc连接mssql2008
			1.创建odbc 2.在 product\11.2.0\dbhome_1\hs\admin\ 下拷贝initdg4odbc,把名字改为initcrmsql(init+所建odbc的名称) HS_FD ... 
- IDEA 安装完码云插件,运行报“Cannot run program "xxx":CreateProcess error=2,系统找不到指定的文件”
			错误:Cannot run program "E:\Program Files\Git\bin\git.exe":CreateProcess error=2,系统找不到指定的文件 ... 
- 开发人员需要具备的DBA技术
			背景 在一些小公司或者部门里,通常很少有专门的DBA职位.这时候就需要我们这些程序员充当业余DBA的作用,去监测和维护数据库性能.本文的目的是帮助非DBA专业的开发人员如何定位和解决日常出现数据库问题 ... 
- Chrome_01_点击 Google搜索结果在新的页面打开
			方法一:Ctrl + 左键 Chrome浏览器中,通过 Ctrl + 左键 ,是在新标签中打开的,通过 Shift + 左键 ,是在新窗口中打开的. 方法二: 1.登录 Google 2.进入下面的设 ... 
- CI中site_url和base_url的区别
			你若使用site_url("test/php/1");则实际url为 http://domain.com/index.php/test/php/1 若使用base_url(&quo ... 
- Wannafly #4 F 线路规划
			数据范围252501 劲啊 Q国的监察院是一个神秘的组织. 这个组织掌握了整个Q国的地下力量,监察着Q国的每一个人. 监察院一共有N个成员,每一个成员都有且仅有1个直接上司,而他只听从其上直接司的命令 ... 
- 1068 Find More Coins (30)(30 分)
			Eva loves to collect coins from all over the universe, including some other planets like Mars. One d ... 
- bzoj 3514: GERALD07加强版 lct+可持久化线段树
			题目大意: N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. 题解: 这道题考试的时候没想出来 于是便爆炸了 结果今天下午拿出昨天准备的题表准备做题的时候 题表里就有这题 ... 
- poj 2187 Beauty Contest —— 旋转卡壳
			题目:http://poj.org/problem?id=2187 学习资料:https://blog.csdn.net/wang_heng199/article/details/74477738 h ... 
