zoukankan      html  css  js  c++  java
  • 【Trie】【枚举约数】Codeforces Round #482 (Div. 2) D. Kuro and GCD and XOR and SUM

    题意:

    给你一个空的可重集,支持以下操作:

    向其中塞进一个数x(不超过100000),

    询问(x,K,s):如果K不能整除x,直接输出-1。否则,问你可重集中所有是K的倍数的数之中,小于等于s-x,并且与x异或结果最大的数是多少(如果不存在这样的数,也输出-1)。

    建立100000个二进制Trie,第i个Trie中存储i的所有倍数。

    查询的时候,在Trie上从高位到低位贪心地找,如果从根到当前点的路径形成的数恰好与s-x相等,要从当前点进行一次dfs统计,看看当前子树中是否存在不超过s-x的数,如果不存在,返回-1。如果当前位恰好小于s-x的当前位,开启一个“限制解除”标记。如果已经开启了此标记,直接返回该点的子树大小是否大于零即可,不必dfs统计。如果没有开启此标记,并且当前位大于s-x的当前位,直接返回-1即可。

    #include<cstdio>
    using namespace std;
    struct Node{
    	int ch[2];
    	Node(){
    		ch[0]=ch[1]=0;
    	}
    };
    Node* trees[100005];
    int *sz[100005];
    int tot[100005];
    bool vis[100005];
    void Insert(int o,int x){
    	int U=1;
    	++sz[o][1];
        for(int i=18-1;i>=0;--i){
        	if(!trees[o][U].ch[(x>>i)&1]){
        		trees[o][U].ch[(x>>i)&1]=++tot[o];
        	}
    		U=trees[o][U].ch[(x>>i)&1];
    		++sz[o][U];
    	}
    }
    void Insert(int x){
    	if(vis[x]){
    		return;
    	}
    	vis[x]=1;
    	for(int i=1;i*i<=x;++i){
    		if(x%i==0){
    			if(i!=x/i){
    				Insert(i,x);
    				Insert(x/i,x);
    			}
    			else{
    				Insert(i,x);
    			}
    		}
    	}
    }
    bool jiechu;
    bool check(int o,int Bit,int lim,int i,int U){
    	if(jiechu || Bit<(lim>>(i-1)&1)){
    		return sz[o][U];
    	}
    	if(Bit>(lim>>(i-1)&1)){
    		return 0;
    	}
    	int sum=0;
    	for(--i;i>=1;--i){
    		int limBit=(lim>>(i-1)&1);
    		if(limBit==1){
    			sum+=sz[o][trees[o][U].ch[0]];
    		}
    		U=trees[o][U].ch[limBit];
    	}
    	sum+=sz[o][U];
    	return sum>0;
    }
    int query(int o,int lim,int W){
    	jiechu=0;
    	int res=0,U=1;
        for(int i=18;i>=1;--i){
            int Bit=((W>>(i-1)&1)^1);
            if(!check(o,Bit,lim,i,trees[o][U].ch[Bit])){
            	Bit^=1;
            	if(!check(o,Bit,lim,i,trees[o][U].ch[Bit])){
            		return -1;
            	}
            }
            if(Bit<(lim>>(i-1)&1)){
            	jiechu=1;
            }
            res+=(1<<(i-1))*Bit;
            U=trees[o][U].ch[Bit];
        }
        return res;
    }
    int q;
    int main(){
    	int op,x,K,s;
    	for(int i=1;i<=100000;++i){
    		tot[i]=1;
    		trees[i]=new Node[20*100000/i];
    		sz[i]=new int[20*100000/i];
    		for(int j=0;j<20*100000/i;++j){
    			sz[i][j]=0;
    		}
    	}
    	scanf("%d",&q);
    	for(;q;--q){
    		scanf("%d%d",&op,&x);
    		if(op==1){
    			Insert(x);
    		}
    		else{
    			scanf("%d%d",&K,&s);
    			if(x%K!=0 || s<=x){
    				puts("-1");
    				continue;
    			}
    			printf("%d
    ",query(K,s-x,x));
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    Neko's loop HDU-6444(网络赛1007)
    Parameters
    SETLOCAL
    RD / RMDIR Command
    devenv 命令用法
    Cannot determine the location of the VS Common Tools folder.
    'DEVENV' is not recognized as an internal or external command,
    How to change Visual Studio default environment setting
    error signing assembly unknown error
    What is the Xcopy Command?:
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/9042921.html
Copyright © 2011-2022 走看看