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

 

posted @ 2020-09-27 11:45  朝暮不思  阅读(188)  评论(0编辑  收藏  举报