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

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

猜你喜欢

转载自blog.csdn.net/sinat_32872703/article/details/80329741