题目链接:http://codeforces.com/contest/979/problem/D
脑残选手大力思考了一下,想出了一个cdq+字典树的三个log的做法,然后就轻易地狗带了...
题解还是厉害啊,直接维护最小值然后就把我的cdq省掉了。剩下部分全是暴力。
我是不是已经是个智障了啊
代码:
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int MAXN=1e5+5;
const int INF=0x3f3f3f3f;
struct node
{
int mi;
node *nxt[2];
node()
{
mi=INF;
memset(nxt,0,sizeof(nxt));
}
};
node pool[MAXN*400],*rt[MAXN],*cur;
vector<int> d[MAXN];
int tot;
node *newnode(int mi)
{
pool[tot].mi=mi;
return &pool[tot++];
}
void init()
{
tot=0;
memset(rt,0,sizeof(rt));
for(int i=1;i<MAXN;i++)
{
for(int j=i;j<MAXN;j+=i)
{
d[j].pb(i);
}
}
for(int i=1;i<MAXN;i++)
{
rt[i]=newnode(INF);
}
}
void add(int x)
{
for(int i=0;i<d[x].size();i++)
{
cur=rt[d[x][i]];
for(int j=18;j>=0;j--)
{
int nxt=(x>>j)&1;
if(cur->nxt[nxt]==NULL)
cur->nxt[nxt]=newnode(x);
cur->mi=min(cur->mi,x);
cur=cur->nxt[nxt];
}
}
}
int query(int k,int x,int v)
{
cur=rt[k];
for(int j=18;j>=0;j--)
{
int now=(x>>j)&1;
if(cur->nxt[now^1]&&cur->nxt[now^1]->mi+x<=v)
cur=cur->nxt[now^1];
else if(cur->nxt[now]&&cur->nxt[now]->mi+x<=v)
cur=cur->nxt[now];
else return -1;
}
return cur->mi;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int q;
init();
scanf("%d",&q);
while(q--)
{
int op;
scanf("%d",&op);
if(op==1)
{
int x;
scanf("%d",&x);
add(x);
}
if(op==2)
{
int x,k,s;
scanf("%d%d%d",&x,&k,&s);
if(__gcd(x,k)%k!=0) puts("-1");
else printf("%d\n",query(k,x,s));
}
}
return 0;
}