码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-05-22 23:58:35      阅读:328      评论:0      收藏:0      [点我收藏+]

标签:eof   最小   bool   memset   一个   math.h   ORC   构建   contest   

题目链接: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+字典树

标签:eof   最小   bool   memset   一个   math.h   ORC   构建   contest   

原文地址:https://www.cnblogs.com/lhclqslove/p/9074276.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!