codeforces 979D. Kuro and GCD and XOR and SUM

codeforces

不大懂这个题怎么一群老哥跑的飞快/kk

异或最大值不难想到Trie,但是还有一个(gcd)的限制比较烦人,注意到(xleq 10^5)(x)的因数个数不会太多,那么我们可以维护(10^5)个Trie,第(k)个表示所有的(k)的倍数的数组成的Trie,那么每次询问只需要询问第(k)个Trie即可,当然首先要保证(k|x)

还剩下一个(vleq s-x)的限制,这个比较轻松,对Trie树上的所有点记录下其子树中的最小值,如果子树的最小值都不满足这个限制就没有必要继续询问下去了

预处理(1- 10^5)中的所有数的所有因数,这个可以(O(nlogn))完成

#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double db;
typedef pair<int,int> pii;
const int N=100000;
const db pi=acos(-1.0);
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define fir first
#define sec second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define maxd 998244353
#define eps 1e-8
int ch[30002000][2],minx[30002000],root[100100],tot=0,val[30002000];
vector<int> fac[100100];

int read()
{
    int x=0,f=1;char ch=getchar();
    while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
    while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
    return x*f;
}

void insert(int &now,int x,int d)
{
	if (!now) {now=(++tot);minx[now]=maxd;}
	minx[now]=min(minx[now],x);
	if (d<0) {val[now]=x;return;}
	insert(ch[now][(x>>d)&1],x,d-1);
}

int query(int now,int lim,int x,int d)
{
	if (d<0) return val[now];
	int ch0=ch[now][0],ch1=ch[now][1];
	if ((!ch0) || (minx[ch0]>lim)) return query(ch1,lim,x,d-1);
	if ((!ch1) || (minx[ch1]>lim)) return query(ch0,lim,x,d-1);
	return query(ch[now][((x>>d)&1)^1],lim,x,d-1);
}

int main()
{
	rep(i,1,N)
		for (int j=i;j<=N;j+=i) fac[j].pb(i);
	int q=read();
	while (q--)
	{
		int op=read();
		if (op==1)
		{
			int x=read(),len=fac[x].size();
			rep(i,0,len-1)
			{
				int y=fac[x][i];
				insert(root[y],x,18);
			}
		}
		else
		{
			int x=read(),k=read(),s=read();
			if ((x%k) || (!minx[root[k]]) || (minx[root[k]]>s-x)) puts("-1");
			else printf("%d
",query(root[k],s-x,x,18));
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/encodetalker/p/11432829.html