hdu5536 Chip Factory (异或最大值)

来源:互联网 发布:linux vi 修改文件 编辑:程序博客网 时间:2024/05/18 12:29

题目:

给 n 个数,从中选出si, sj, sk使得(si+sj)sk最大,输出最大值。n1000,si109

分析:

看见异或就换二进制。
枚举sisj,对于每个和,都在字典树里逐位找使得异或结果最大的那个。找之前把si,sj从树里删掉。

注意字典树不一定非要对字符串操作,没必要把数字先变成字符串再操作。对于x, 逐位 x&(1 << i) 就可以得到每一位。同时,找的时候可以直接算出答案,而不用把最优串存下来再算结果。不要拘泥于模板。

代码:

#include <iostream>#include <algorithm>#include <queue>#include <stack>#include <vector>#include <map>#include <set>#include <cmath>#include <cstdlib>#include <cstring>#include <cstdio>using namespace std;#define ms(a,b) memset(a,b,sizeof(a))#define lson rt*2,l,(l+r)/2#define rson rt*2+1,(l+r)/2+1,rtypedef unsigned long long ull;typedef long long ll;const int MAXN=1e3+5;const double EPS=1e-8;const int INF=0x3f3f3f3f;const int MOD = 1e9+7;struct Trie{    int n;      Trie *next[2]; };Trie tree[MAXN*MAXN];int n,a[MAXN];char ans[MAXN];int tot=-1;void create(){    ++tot;    tree[tot].n=0;    for(int i=0;i<2;i++)        tree[tot].next[i]=NULL;}void init(){    tot=-1;    create();}void insert(int x){    Trie *r=&tree[0];    for(int i=30;i>=0;i--){        int k = (x & (1 << i)) > 0;        if(r->next[k]){            r=r->next[k];            r->n++;        }        else{            create();            r->next[k]=&tree[tot];            r=&tree[tot];            r->n++;        }    }}void erase(int x){    Trie *r=&tree[0];    for(int i=30;i>=0;i--){        int k = (x & (1 << i)) > 0;        r=r->next[k];        r->n--;    }}int search(int x){    Trie* r=&tree[0];    int ret = 0;    for(int i=30;i>=0;i--){        int k = !((x & (1 << i)) > 0);        Trie* l1 = r->next[k],*l2 = r->next[1-k];        if(l1 && l1->n){            r = l1;            ret += (1 << i);        }        else{            r = l2;        }       }    return ret;}int main(){    int T;    scanf("%d",&T);    while(T--){        scanf("%d",&n);        init();        for(int i=0;i<n;i++){            scanf("%d",&a[i]);            insert(a[i]);        }        int Ans = 0;        for(int i=0;i<n;i++){            for(int j=i+1;j<n;j++){                erase(a[i]);                erase(a[j]);                Ans = max(Ans,search(a[i]+a[j]));                insert(a[i]);                insert(a[j]);            }        }        printf("%d\n",Ans);         }    return 0;}
原创粉丝点击