题目链接: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 <string.h> 4 #include <algorithm> 5 #include <stdio.h> 6 #include <math.h> 7 #define ll long long 8 #define pb push_back 9 using namespace std; 10 const int N=800010; 11 const int INF=1<<30; 12 const int inf=0x3f3f3f3f; 13 const int maxn=1e5+10; 14 const int mod=1e9+7; 15 bool vis[maxn];int q; 16 struct tire//字典树 17 { 18 int mi[maxn*32],sz,rt,now; 19 struct node 20 { 21 int nxt[2]; 22 }st[maxn*32]; 23 int node()//构建新节点 24 { 25 st[sz].nxt[0]=st[sz].nxt[1]=-1; 26 sz++;return sz-1; 27 } 28 void init() 29 { 30 memset(mi,inf,sizeof(mi));//初始化每个节点后插入的最小值 31 sz=0; 32 rt=node(); 33 } 34 void ins(int x)//插入 35 { 36 now=rt; 37 mi[now]=min(mi[now],x); 38 for(int i=31;i>=0;i--) 39 { 40 int id=(x>>i)&1; 41 if(st[now].nxt[id]==-1)st[now].nxt[id]=node(); 42 now=st[now].nxt[id]; 43 mi[now]=min(mi[now],x); 44 } 45 } 46 int find(int x,int lim)//查值 47 { 48 now=rt; 49 if(mi[now]>lim)return -1;//如果最小值比限制条件s-x大返回-1 50 for(int i=31;i>=0;i--) 51 { 52 int id=(x>>i)&1; 53 if(st[now].nxt[id^1]!=-1&&mi[st[now].nxt[id^1]]<=lim) 54 id^=1; 55 now=st[now].nxt[id]; 56 } 57 return mi[now]; 58 } 59 }ac; 60 int main() 61 { 62 ac.init(); 63 scanf("%d",&q); 64 while(q--) 65 { 66 int op,u,x,k,s; 67 scanf("%d",&op); 68 if(op==1) 69 { 70 scanf("%d",&u);vis[u]=true; 71 ac.ins(u); 72 } 73 else 74 { 75 scanf("%d %d %d",&x,&k,&s); 76 if(x%k!=0) 77 { 78 printf("-1\n"); 79 } 80 else if(k==1) 81 { 82 printf("%d\n",ac.find(x,s-x)); 83 } 84 else 85 { 86 int ans=-1,mx=-1; 87 for(int i=k;i<=s-x;i+=k) 88 { 89 if(vis[i]&&(x^i)>mx) 90 { 91 ans=i;mx=(x^i); 92 } 93 } 94 printf("%d\n",ans); 95 } 96 } 97 } 98 return 0; 99 }
Codeforces Round #482 (Div. 2)D. Kuro and GCD and XOR and SUM+字典树
原文:https://www.cnblogs.com/lhclqslove/p/9074276.html