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(x,v)  (即gcd(x,v)是k的倍数,v+x <= k, x ^ v的值最大。

题解:XOR亦或问题是经典的题目,一般都是用01字典树去处理。 然后需要满足条件1, 所以我们可以对于每一个点建立一个字典树,每次添加数的时候都往这个数的因子添加这个值,这样我们直接访问对应的k就可以找到答案了。

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
 4 #define LL long long
 5 #define ULL unsigned LL
 6 #define fi first
 7 #define se second
 8 #define pb push_back
 9 #define lson l,m,rt<<1
10 #define rson m+1,r,rt<<1|1
11 #define max3(a,b,c) max(a,max(b,c))
12 #define min3(a,b,c) min(a,min(b,c))
13 typedef pair<int,int> pll;
14 const int INF = 0x3f3f3f3f;
15 const LL mod = 1e9+7;
16 const int N = 1e5+10;
17 vector<int> son[N];
18 struct Node{
19     int Min;
20     Node * p[2];
21     Node(){
22         Min = INF;
23         p[0] = p[1] = nullptr;
24     }
25 }*rt[N];
26 bool vis[N];
27 void init(){
28     for(int i = 1; i < N; i++){
29         rt[i] = new Node();
30         for(int j = i; j < N; j+=i){
31             son[j].pb(i);
32         }
33     }
34 }
35 void Add(int k, int u){
36     Node *tmp = rt[k];
37     tmp -> Min = min(tmp -> Min, u);
38     for(int i = 18; i >= 0; i--){
39         int id = u>>i & 1;
40         if(tmp -> p[id] == nullptr)
41             tmp -> p[id] = new Node();
42         tmp = tmp -> p[id];
43         tmp -> Min = min(tmp -> Min, u);
44     }
45 }
46 int Query(int x, int k, int s){
47     Node *tmp = rt[k];
48     if(x%k != 0 || tmp->Min+x > s)
49         return -1;
50     int ret = 0;
51     for(int i = 18; i >= 0; i--){
52         int id = x >> i & 1;
53         if(tmp -> p[id^1] != nullptr && tmp -> p[id^1] -> Min + x <= s){
54             tmp = tmp -> p[id^1];
55             ret += (id^1) << i;
56         }
57         else {
58             tmp = tmp -> p[id];
59             ret += id << i;
60         }
61     }
62     return ret;
63 }
64 int main(){
65     ///Fopen;
66     init();
67     int q, t, u, x, s, k;
68     scanf("%d", &q);
69     while(q--){
70         scanf("%d", &t);
71         if(t == 1){
72             scanf("%d", &u);
73             if(!vis[u]){
74                 vis[u] = 1;
75                 for(int k : son[u]){
76                     Add(k, u);
77                 }
78             }
79         }
80         else{
81             scanf("%d%d%d", &x, &k, &s);
82             printf("%d\n", Query(x,k,s));
83         }
84     }
85     return 0;
86 }
View Code

猜你喜欢

转载自www.cnblogs.com/MingSD/p/9057734.html