D. Kuro and GCD and XOR and SUM

Kuro is currently playing an educational game about numbers. The game focuses on the greatest common divisor (GCD), the XOR value, and the sum of two numbers. Kuro loves the game so much that he solves levels by levels day by day.

Sadly, he‘s going on a vacation for a day, and he isn‘t able to continue his solving streak on his own. As Katie is a reliable person, Kuro kindly asked her to come to his house on this day to play the game for him.

Initally, there is an empty array aa. The game consists of qq tasks of two types. The first type asks Katie to add a number uiui to aa. The second type asks Katie to find a number vv existing in aa such that ki∣GCD(xi,v)ki∣GCD(xi,v), xi+v≤sixi+v≤si, and xi⊕vxi⊕v is maximized, where ⊕⊕denotes the bitwise XOR operation, GCD(c,d)GCD(c,d) denotes the greatest common divisor of integers cc and dd, and y∣xy∣x means xx is divisible by yy, or report -1 if no such numbers are found.

Since you are a programmer, Katie needs you to automatically and accurately perform the tasks in the game to satisfy her dear friend Kuro. Let‘s help her!

Input

The first line contains one integer qq (2≤q≤1052≤q≤105) — the number of tasks the game wants you to perform.

qq lines follow, each line begins with an integer titi — the type of the task:

  • If ti=1ti=1, an integer uiui follow (1≤ui≤1051≤ui≤105) — you have to add uiui to the array aa.
  • If ti=2ti=2, three integers xixi, kiki, and sisi follow (1≤xi,ki,si≤1051≤xi,ki,si≤105) — you must find a number vv existing in the array aa such that ki∣GCD(xi,v)ki∣GCD(xi,v), xi+v≤sixi+v≤si, and xi⊕vxi⊕v is maximized, where ⊕⊕ denotes the XOR operation, or report -1 if no such numbers are found.

It is guaranteed that the type of the first task is type 11, and there exists at least one task of type 22.

Output

For each task of type 22, output on one line the desired number vv, or -1 if no such numbers are found.

Examples

input

51 11 22 1 1 32 1 1 22 1 1 1

output

21-1

input

101 92 9 9 222 3 3 181 252 9 9 202 25 25 141 202 26 26 31 142 20 20 9

output

999-1-1-1

Note

In the first example, there are 5 tasks:

  • The first task requires you to add 11 into aa. aa is now {1}{1}.
  • The second task requires you to add 22 into aa. aa is now {1,2}{1,2}.
  • The third task asks you a question with x=1x=1, k=1k=1 and s=3s=3. Taking both 11 and 22 as vv satisfies 1∣GCD(1,v)1∣GCD(1,v) and 1+v≤31+v≤3. Because 2⊕1=3>1⊕1=02⊕1=3>1⊕1=0, 22 is the answer to this task.
  • The fourth task asks you a question with x=1x=1, k=1k=1 and s=2s=2. Only v=1v=1 satisfies 1∣GCD(1,v)1∣GCD(1,v) and 1+v≤21+v≤2, so 11 is the answer to this task.
  • The fifth task asks you a question with x=1x=1, k=1k=1 and s=1s=1. There are no elements in aa that satisfy the conditions, so we report-1 as the answer to this task.

这题其实可以说是01字典树的裸题,  看了别人的题解 然后就去学了一下01字典树

现在我也只是刚刚学有点懵逼

我看这篇博客学的 转载

源地址https://blog.csdn.net/riba2534/article/details/80344026

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<vector>
  5 #include<queue>
  6 #define inf 0x3fffffff
  7
  8 using namespace std;
  9 typedef long long LL;
 10 const int maxn = 2e5 + 10;
 11 int a[maxn], minn[maxn], tree[32 * maxn][2];
 12 int sum, root;
 13 int newnode() {
 14     tree[sum][0] = tree[sum][1] = -1;
 15     sum++;
 16     return sum - 1;
 17 }
 18
 19 void init() {
 20     sum = 0 ;
 21     memset(minn, 0x3f, sizeof(minn));
 22     root = newnode();
 23 }
 24
 25 /*
 26 void add(int x) {
 27     int p = x;
 28     int now = root;
 29     minn[now] = min(minn[now], p);
 30     for (int i = 31 ; i >= 0 ; i--) {
 31         int to = (x >> i ) & 1;
 32         if (tree[now][to] == -1)  tree[now][to] = newnode();
 33         now = tree[now][to];
 34         minn[now] = min(minn[now], p);
 35     }
 36 }*/
 37 void add(int x) {
 38     int p = x;
 39     int now = root ;
 40     minn[now] = min(minn[now], p);
 41     for (int i = 31 ; i >= 0 ; i--) {
 42         int  to = (x >> i) & 1;
 43         if (tree[now][to] == -1)  tree[now][to] = newnode();
 44         now = tree[now][to];
 45         minn[now] = min(minn[now], p);
 46     }
 47 }
 48 /*
 49 int getans(int x, int p) {
 50     int now = root;
 51     if (minn[now] > p) return -1;
 52     for (int i = 31 ; i >= 0 ; i-- ) {
 53         int to = (x >> i) & 1 ;
 54         if (tree[now][to ^ 1] != -1 && minn[tree[now][to ^ 1]] <= p   ) to ^= 1;
 55         now = tree[now][to];
 56     }
 57     return minn[now];
 58 }*/
 59 int getans(int x, int p) {
 60     int now = root ;
 61     if (minn[now] > p ) return -1;
 62     for (int i = 31 ; i >= 0 ; i--  ) {
 63         int to = (x >> i) & 1;
 64         if (tree[now][to ^ 1] != -1 && minn[tree[now][to ^ 1]] <= p ) to ^= 1;
 65         now = tree[now][to];
 66     }
 67     return minn[now];
 68 }
 69 int main() {
 70     int t, op, x, k, s;
 71     init();
 72     scanf("%d", &t);
 73     while(t--) {
 74         scanf("%d", &op);
 75         if (op == 1) {
 76             scanf("%d", &x);
 77             a[x] = 1;
 78             add(x);
 79         } else {
 80             scanf("%d%d%d", &x, &k, &s);
 81             if (x % k != 0) {
 82                 printf("-1\n");
 83                 continue;
 84             }
 85             if (k == 1) {
 86                 printf("%d\n", getans(x, s - x));
 87                 continue;
 88             }
 89             int maxn = -1, ans = -1;
 90             for (int i = k ; i <= s - x ; i += k)  {
 91                 if (a[i] && (i ^ x) > maxn) {
 92                     maxn = i ^ x;
 93                     ans = i;
 94                 }
 95             }
 96             printf("%d\n", ans);
 97         }
 98     }
 99     return 0;
100 }

原文地址:https://www.cnblogs.com/qldabiaoge/p/9052870.html

时间: 2024-10-06 21:14:08

D. Kuro and GCD and XOR and SUM的相关文章

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),求当前所有数中满足,k|v,x+v<=s,且\(x\oplus v\)最大的v. 做法好神啊.关于异或的问题有一种常见做法,就是利用01trie来查找在一堆数里面,那个数与x的异或值最大.这道题就是这个思路.如果去掉k必须整除v这个条件,那么就转化成了上一个问题(只不过有最大

Codeforces Round #482 (Div. 2)D. Kuro and GCD and XOR and SUM+字典树

题目链接:D. Kuro and GCD and XOR and SUM 题意:两种操作:第一种给数组添加一个数,第二种输入x,k,s,要求从数组中找到一个数v,要求k能整除gcd(k,v);并且v<=s-x,然后异或v与k的异或值最大. 题解:对与k大于1的情况我们暴力枚举过去,k为1的特殊处理建一颗字典树,如果可以的满足条件的话,每次取值时往相反方向取. 1 #include<bits/stdc++.h> 2 #include <iostream> 3 #include

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|gcd(a,x)$:现在需要找满足条件的$a$,它异或$x$的值最大.$x,k,s \leq 10^5$ 操作数$q \leq 10^5$ 这道题就是看你想到一个算法有没有去算算实际复杂度 我们发现,对于所有在$[1,10^5]$的$i$,$10^5$之内的$i$的倍数的个数和,并不是很大,只有$2*1

【UVA12716】GCD和XOR

题意 输入整数n(1<=n<=3*107),有多少对整数(a,b)满足:1<=b<=a<=n,且gcd(a,b)=a XOR b.例如:n=7时,有4对:(3,2),(5,4),(6,4),(7,6) 分析 本题的主要想法就是找到一个沟通gcd(a,b)和a^b的桥梁 a^b≥a-b.口头化证明:假如二进制位上相同,那么都是0,加入二进制位上不同,前者一定是1,后者可能是1(1-0),也有可能借位导致数位减少(0-1) a-b≥gcd(a,b).由九章算术·更相减损术可得gc

GCD和XOR题解

由题意 我们要统计1~N中有多少二元组(a,b)满足gcd(a,b) ==a XOR b 首先有如下性质: 1.a XOR b >= a-b  (a >= b) 证明:(给个简单的证明 OI证明都不严谨的) 在二进制下 a XOR b :b某一位的1才对答案有影响,如果a那位为1那就相当于减,为0相当于加 a 减     b: 同样b的某一为的1才对答案影响,且a的那一位不管是0还是1,都是减 所以 a XOR b 一定 >= a-b 2. a - b >= gcd( a,b )

Xor and Sum(位运算)

题目描述 给定一个大小为N的数组A,第i个元素为Ai. 问有多少的子区间[LR],满足区间数值异或和等于区间数值和,即: Al xor Al+1 xor…xor Ar = Al + Al+1 +…+Ar(l+1表示下标)      a和b的xor即为a和b二进制表示按位取xor得到新数c的十进制表示5和12的xor计算如下: 510=01012 (12)10=(1100)2 01012xor11002=(1001)2 (1001)2=(9)10 输入 第一行给定一个整数N.第二行给定N个整数,第

例题10-5 GCD等于XOR UVa12716

1.题目描述:点击打开链接 2.解题思路:本题能用的判断条件只有两个:(1)gcd(a,b)=c:(2)(a^b)=c:通过观察容易发现如果gcd(a,b)=(a^b)=c,那么c=a-b,因此可以事先枚举所有a的因数c,利用b=a-c计算b,然后只需验证是否满足(a^b)==c即可.但本题的数据太大,而且枚举约数不容易,因此可以利用约数c枚举倍数a,这样就会方便很多,打表的效率也足够高:而且,由于a=k*c,b=a-c=(k-1)*c,因此,必有gcd(a,b)=gcd(k*c,(k-1)*c

UVa 12716 (GCD == XOR) GCD XOR

题意: 问整数n以内,有多少对整数a.b满足(1≤b≤a)且gcd(a, b) = xor(a, b) 分析: gcd和xor看起来风马牛不相及的运算,居然有一个比较"神奇"的结论: 设gcd(a, b) = xor(a, b) = c, 则 c = a - b 这里 有比较严格的证明. 有了这个结论后,我们可以枚举约数c,然后枚举c的倍数a,再根据c = a - b计算b,检验b是否满足gcd(a, b) = xor(a, b) 1 #include <cstdio> 2

gcd的性质+分块 Bzoj 4028

4028: [HEOI2015]公约数数列 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 865  Solved: 311[Submit][Status][Discuss] Description 设计一个数据结构. 给定一个正整数数列 a_0, a_1, ..., a_{n - 1},你需要支持以下两种操作: 1. MODIFY id x: 将 a_{id} 修改为 x. 2. QUERY x: 求最小的整数 p (0 <= p < n),使