题意:

给出两种操作:

1.添加一个数字x到数组。

2.给出s,x,k,从数组中找出一个数v满足gcd(x,k) % v == 0 && x + v <= s && (x xor v 最大),如果没有,输出-1.

思路:

有两种做法。

第一种,首先用若干个set存因子中有k的数字。

然后每次在set[k]中二分找到大于s-x的第一个数,然后从大到小开始找,假设sum为当前x xor v的最大值,那么当当前的*it +x < sum,那么就直接break,原理是因为a ^ b <= a + b。

这个没有优化之前是会tle,但是加了优化之后比字典树跑得快了许多。。。

第二种,对于每一个数,都把它添加到它的因子的01字典树当中去,然后根据x xor v最大这个经典问题,找 xor 最大,字典树是个好东西。

代码1;

 #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <set>
#include <math.h>
using namespace std;
const int N = 1e5 + ;
set<int> mmp[N];
int main()
{
int n;
scanf("%d",&n);
while (n--)
{
int t;
scanf("%d",&t);
if (t == )
{
int u;
scanf("%d",&u);
int m = sqrt(1.0 * u);
for (int i = ;i <= m;i++)
{
if (u % i == )
{
mmp[i].insert(u);
mmp[u/i].insert(u);
}
}
}
else
{
int x,k,s;
scanf("%d%d%d",&x,&k,&s);
int sum = -;
int ans = -;
if (x % k)
{
printf("%d\n",ans);
continue;
}
auto it = mmp[k].upper_bound(s-x);
if (mmp[k].empty() || it == mmp[k].begin())
{
printf("%d\n",ans);
continue;
}
--it;
for (;it != mmp[k].begin();--it)
{
if (sum > x + *it) break;
if (sum < (x ^ *it))
{
ans = *it;
sum = x ^ *it;
}
}
if (sum < (x ^ *it))
{
ans = *it;
sum = x ^ *it;
}
printf("%d\n",ans);
}
}
return ;
}

代码2:

 #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stdlib.h>
#include <set>
using namespace std;
const int N = 1e5 + ;
set<int> g[N];
struct node
{
int mi;
struct node* bit[];
node()
{
mi = N;
bit[] = bit[] = nullptr;
}
};
node *a[N];
void update(int x,int u)
{
node* cu = a[x];
cu -> mi = min(cu -> mi,u);
for (int i = ;i >= ;i--)
{
int b = u >> i & ;
if (cu -> bit[b] != nullptr)
{
cu = cu -> bit[b];
cu -> mi = min(cu -> mi,u);
}
else
{
cu -> bit[b] = new node();
cu = cu -> bit[b];
cu -> mi = min(cu -> mi,u);
}
}
}
int que(int x,int k,int s)
{
node *cu = a[k];
if (x % k || cu -> mi > s - x) return -;
int ret = cu -> mi;
for (int i = ;i >= ;i--)
{
int b = x >> i & ;
if (cu -> bit[b^] != nullptr && cu -> bit[b^] -> mi + x <= s)
{
cu = cu -> bit[b^];
ret = cu -> mi;
}
else
{
cu = cu -> bit[b];
ret = cu -> mi;
}
}
return ret;
}
int main()
{
int q;
for (int i = ;i < N;i++)
{
for (int j = i;j < N;j += i)
{
g[j].insert(i);
}
}
for (int i = ;i < N;i++) a[i] = new node();
scanf("%d",&q);
while (q--)
{
int t;
scanf("%d",&t);
if (t==)
{
int u;
scanf("%d",&u);
for (auto x : g[u])
{
update(x,u);
}
}
else
{
int x,s,k;
scanf("%d%d%d",&x,&k,&s);
int ans = que(x,k,s);
printf("%d\n",ans);
}
}
return ;
}

codeforces 979D Kuro and GCD and XOR and SUM的更多相关文章

  1. 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, ...

  2. 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 ...

  3. 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( ...

  4. D. Kuro and GCD and XOR and SUM

    Kuro is currently playing an educational game about numbers. The game focuses on the greatest common ...

  5. 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 ...

  6. 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 ...

  7. 【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,并 ...

  8. cf979d Kuro and GCD and XOR and SUM

    set做法 正解是trie-- 主要是要学会 \(a\ \mathrm{xor}\ b \leq a+b\) 这种操作 #include <iostream> #include <c ...

  9. 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 ...

随机推荐

  1. Aidl跨进程通信机制-android学习之旅(87)

    Aidl简介 AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信的代码. 如果在 ...

  2. Android群英传笔记——第十二章:Android5.X 新特性详解,Material Design UI的新体验

    Android群英传笔记--第十二章:Android5.X 新特性详解,Material Design UI的新体验 第十一章为什么不写,因为我很早之前就已经写过了,有需要的可以去看 Android高 ...

  3. 如何实现 集群化/Session 复制-doc(cluster-howto.html)

    源文档链接: http://tomcat.apache.org/tomcat-6.0-doc/cluster-howto.html 翻译日期: 2014年3月19日 翻译人员: 铁锚 感受: Tomc ...

  4. saiku显示不出新的cube(加载的cube,saiku会保存到缓存中,不重新加载)

    当用workbench 修改cube后,保存到saiku路径. saiku读取该cube时,如果以前加载过该cube(同路径,同名).则不会新加载,而是用缓存中的cube,这个cube是以前的cube ...

  5. Linux常用命令(第二版) --系统开关机命令

    系统开关机命令 说明-服务器不会经常的关机,重启,没有故障,服务器不会关机.因此这些命令就显得不是很常用. 1.shutdown /usr/sbin/shutdown e.g. shutdown -h ...

  6. Android adb基本命令-cd,ls,目录相关命令

    cd的命令 cd -:代表进入家目录,普通用户是/home/用户名,root用户是/root目录,-是家目录的代表 cd /:这是进入根目录,/是根目录的代表 cd .. :是返回上一级的目录 cd ...

  7. LeetCode之“动态规划”:Interleaving String

    题目链接 题目要求: Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. For example ...

  8. C++项目中的extern "C" {}(转)

    注:本文转自吴秦先生的博客http://www.cnblogs.com/skynet/archive/2010/07/10/1774964.html#.吴秦先生的博客写的非常详细深刻容易理解,故特转载 ...

  9. OpenCV——色调映射

    // define head function #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITHM_H_INCLUDED #include < ...

  10. Objective-C的面向对象特性(一)

    Objective-C在c语言的基础上增加了面向对象特性,都有哪些面向对象特性呢? 其中第一个最重要的特性是类和对象的实现. Objective-C软件由许多对象构成,形成一个对象网络,对象之间通过发 ...