Topic link: Kuro and GCD and XOR and SUM
meaning of the title
Initially, there is an empty set with qq operations. Each operation has two choices:
- Given uiui, it means adding uiui to the collection.
- Given xi, ki, Si xi, ki, si, an integer v v is found from the set, requiring V V to satisfy the conditions ki|gcd(xi,v),xi+v < Si ki|gcd(xi,v),xi+v < Si and Xi V Xi V to have the maximum value.
input
The first action is an integer q (2 < q < 105)q (2 < q < 105), followed by q Q q lines, each of which can be in the following two formats:
- The first number is 11, followed by an integer ui (1 < ui < 105)ui (1 < ui < 105), indicating the first operation;
- The first number is 22, followed by three integers xi, ki. Si xi, ki. si, indicating operation 22.
output
For each operation 22, if a valid vv can be found, the value of vv will be output, otherwise the output will be_1_1.
Example
input |
---|
5 1 1 1 2 2 1 1 3 2 1 1 2 2 1 1 1 |
output |
2 1 -1 |
Tips |
1. If the number 11 is added to the set, the set is {1} {1}; 2. If the number 22 is added to the set, the set is {1,2} {1,2}; 3.1 | GCD (1,1), 1 + 1 < 2,1 1=0;1|gcd(1,2),1+2 < 3,1 2=31|gcd(1,1),1+1 < 2,1 1=0;1|gcd(1,2),1+2 < 3, 1 2 = 3, so the answer is 22; 4. Only 11 satisfy the first two conditions, so the answer is 11. 5. The answer is 1_1 because the number that meets the criteria cannot be found. |
input |
---|
10 1 9 2 9 9 22 2 3 3 18 1 25 2 9 9 20 2 25 25 14 1 20 2 26 26 3 1 14 2 20 20 9 |
output |
9 9 9 -1 -1 -1 |
Title Solution
If Kiki can't divide xixi, output directly_1_1. If it can divide, the answer is to find out all the multiples of kiki, and build 105105105 dictionary trees. The ii dictionary tree contains all the multiples of ii in the set. So every time a digital UI is added, the uiui is added to all the approximate dictionary trees of kiki. For every 22 operations, it is directly in the kk dictionary tree. Finding the answer that satisfies the condition on the tree requires O (nln n) O (nln n) to preprocess all approximations.
Past title code
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <functional>
#include <algorithm>
using namespace std;
#define LL long long
const int maxn = 100000 + 100;
vector<vector<int> > tree;
vector<int> Min;
int cnt;
bool vis[maxn];
struct Trie {
int root;
int creat(int x) {
int ret = cnt;
++cnt;
tree.push_back(vector<int>(2, -1));
Min.push_back(x);
return ret;
}
void Init() {
root = creat(1000000000);
}
int id(int x, int Index) {
return ((x >> (20 - Index)) & 1);
}
void add(int x) {
int pos = root;
Min[pos] = min(Min[pos], x);
for(int i = 0; i <= 20; ++i) {
int w = id(x, i);
if(tree[pos][w] == -1) {
tree[pos][w] = creat(x);
}
pos = tree[pos][w];
Min[pos] = min(Min[pos], x);
}
}
int query(int x, int s) {
int ret = 0;
int num = 0;
int pos = root;
for(int i = 0; i <= 20; ++i) {
int w = !id(x, i);
if(tree[pos][w] == -1 || Min[tree[pos][w]] > s) {
w = !w;
} else {
ret |= (1 << (20 - i));
}
if(tree[pos][w] == -1 || Min[tree[pos][w]] > s) {
return -1;
}
num |= (w << (20 - i));
pos = tree[pos][w];
}
return num;
}
};
int q, command, x, k, s;
Trie t[maxn];
vector<int> fac[maxn];
int main() {
#ifdef LOCAL
freopen("test.txt", "r", stdin);
// freopen("10.out", "w", stdout);
#endif // LOCAL
for(int i = 1; i < maxn; ++i) {
t[i].Init();
for(int j = i; j < maxn; j += i) {
fac[j].push_back(i);
}
}
scanf("%d", &q);
for(int i = 0; i < q; ++i) {
scanf("%d", &command);
if(command == 1) {
scanf("%d", &x);
if(vis[x]) {
continue;
}
vis[x] = true;
int len = fac[x].size();
for(int j = 0; j < len; ++j) {
int num = fac[x][j];
t[num].add(x);
}
} else {
scanf("%d%d%d", &x, &k, &s);
if(x % k != 0 || s <= x) {
printf("-1\n");
} else {
printf("%d\n", t[k].query(x, s - x));
}
}
}
return 0;
}