题目链接: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; }