zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    Java函数式接口与逐步lambda简化
    Java继承知识点总结(基础知识3)
    Java静态工厂方法新建对象
    Java对象与类知识点总结(基础知识2)
    Java多线程并发入门(基础知识)
    Java基本程序设计结构(基础知识1)
    【数据库】JDBC课设(5)将图片以二进制流方法添加进MySQL并查询
    【数据库】JDBC课设(4) DatabaseMetaData 获得数据库信息
    【数据库】JDBC课设(3)TYPE_SCROLL_INSENSITIVE使结果集可以前后滚动
    简单总结.net下几种序列化
  • 原文地址:https://www.cnblogs.com/encodetalker/p/11432829.html
Copyright © 2011-2022 走看看