题意:

给出两种操作:

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. Swift基础之UITextField

    //设置全局变量,将下面的替换即可     //var myTextField = UITextField();     //系统生成的viewDidLoad()方法     override fun ...

  2. Android For JNI(二)——C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器

    Android For JNI(二)--C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器 当我们把Hello World写完之后,我们就可以迈入C的大门了,今天就来讲讲基本的一些数据类型 ...

  3. 不要使用jQuery触发原生事件

    原文链接: DO NOT TRIGGER REAL EVENT NAMES WITH JQUERY! 原文日期: 2014年02月26日 翻译日期: 2014年03月2日 翻译人员: 铁锚 JavaS ...

  4. ITU-T Technical Paper: IP服务性能模型

    本文翻译自ITU-T的Technical Paper:<How to increase QoS/QoE of IP-based platform(s) to regionally agreed ...

  5. PS图层混合算法之一(不透明度,正片叠底,颜色加深,颜色减淡)

    下列公式中,A代表了上面图层像素的色彩值(A=像素值/255),B代表下面图层像素的色彩值(B=像素值/255),C代表了混合像素的色彩值(真实的结果像素值应该为255*C).该公式也应用于层蒙板. ...

  6. 【Android 应用开发】BluetoothSocket详解

    一. BluetoothSocket简介 1. 简介 客户端与服务端 : BluetoothSocket 和 BluetoothServerSocket 类似于Java中的套接字的 Socket 和 ...

  7. ASP.NET Core 2.0 使用NLog实现日志记录

    1.安装NuGet包 1.Install-Package NLog.Web.AspNetCore 2.Install-Package NLog 在csproj中编辑: <PackageRefer ...

  8. Linux的关机详解

    Linux如果是关机不想Windows,特别是命令界面.如果使用的是虚拟机,我们经常通过虚拟机来关闭.有点笨重啊.着特意找到关于Linux关机命令分享给大家. 在linux下一些常用的关机/重启命令有 ...

  9. Linux的chkconfig命令详解

    chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. 使用语法: chkconfig [--a ...

  10. LINQ、Lambda与委托

    首先定义个Person类: public class Person { public string Name{get;set;} //姓名 public int Age{get;set;} //年龄 ...