• CF979D Kuro and GCD and XOR and SUM(01Trie)


    看到异或最大值,很容易想到01trie

    现在的问题是多了几个约束条件。我们观察第一个条件,就是要求v的大小,这个很好维护,只需要维护最小值就行。

    问题是第二个条件,第一步我们发现这个条件等价于x%k==0&&v%k==0.

    简单的证明一下,首先如果一个数整除两个数的最大公约数,如果某一个数不是他的倍数,显然不可能。

    当他们是他的倍数,那么他们的最大公约数也能整除这个数,最大公约数永远会包括这个k。

    现在的问题是如何建trie,这里需要一些思维,发现数不会大于1e5,因此我们对于每个数都建一个trie

    而插入的时候,把这个数插进他的所有约数当中,这个约数需要预处理。这样我们选择的k,答案就在k的trie上,之后就是贪心异或

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=1e5+10;
    const int inf=1e9;
    int tr[N*18*18][2],rt[N];
    int mi[N*18*18];
    int vis[N];
    int st[N];
    int cnt;
    vector<int> d[N];
    void init(){
        int i,j;
        for(i=1;i<=1e5;i++){
            for(j=i;j<=1e5;j+=i){
                d[j].push_back(i);
            }
        }
    }
    void insert(int rt,int x){
        int p=rt;
        mi[p]=min(mi[p],x);
        for(int i=18;i>=0;i--){
            int sign=x>>i&1;
            if(!tr[p][sign]){
                tr[p][sign]=++cnt;
            }
            p=tr[p][sign];
            mi[p]=min(mi[p],x);
        }
    }
    int query(int k,int x,int s){
        int p=rt[k];
        if(x%k!=0||mi[p]+x>s)
            return -1;
        ll ans=0;
        for(int i=18;i>=0;i--){
            int sign=x>>i&1;
            if(tr[p][!sign]&&mi[tr[p][!sign]]+x<=s){
                ans+=((sign^1)<<i);
                p=tr[p][!sign];
            }
            else{
                ans+=(sign<<i);
                p=tr[p][sign];
            }
        }
        return ans;
    }
    int main(){
        ios::sync_with_stdio(false);
        init();
        int q;
        cin>>q;
        int mx=N*18*18;
        for(int i=0;i<mx;i++){
            mi[i]=inf;
        }
        while(q--){
            int opt;
            cin>>opt;
            if(opt==1){
                int u;
                cin>>u;
                if(st[u])
                    continue;
                st[u]=1;
                for(auto x:d[u]){
                    if(!vis[x]){
                        rt[x]=++cnt;
                        vis[x]=1;
                    }
                    insert(rt[x],u);
                }
            }
            else{
                int x,k,s;
                cin>>x>>k>>s;
                cout<<query(k,x,s)<<endl;
            }
        }
        return 0;
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    JSP application用法
    JSP到底内置了几大对象?
    ConcurrentHashMap之实现细节 5
    假如我是JAVA开发人员
    jBPM
    ServletContext与ServletConfig分析
    oracle建立索引原则
    70个新鲜实用的JavaScript和Ajax技术(上)
    ConcurrentHashMap之实现细节
    ConcurrentHashMap之实现细节3
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13738530.html
Copyright © 2020-2023  润新知