HDU5536 Chip Factory Trie(01字典树)

来源:互联网 发布:手机兼职打字员软件 编辑:程序博客网 时间:2024/06/05 15:11

题意:

给出n(3n1000)n(3≤n≤1000)个数字,求max(si+sj)skmax(si+sj)⨁sk,而且i,j,ki,j,k互不相等。

分析:

把每个数字看成一个0101字符串插入倒Trie树中去,枚举iijj,然后把sisisjsj从Trie树中删去。
然后在Trie树中贪心找到能与si+sjsi+sj异或得到的最大值。
具体匹配的过程中是这样的,首先看树中最高位能否异或得到11
能的话就往能的那个方向走,否则往另外一个方向走。

另外删除操作是这样实现的,我们每个节点记录一个valval值。
插入时对所有经过节点的valval值加11,删除就将对应节点的valval值减11
在树上匹配的时候就只走那些val

val值为正的节点。


#include<bits/stdc++.h>using namespace std;const int maxn = 1010;const int maxnode = 1e5+10;int sz;//总共节点个数int s[maxn], ch[maxnode][2], val[maxnode];void init(){    sz = 1;    memset(ch[0], 0, sizeof(ch[0]));}//d=1表示插入,d=-1表示删除void update(int v, int d){    int u = 0;    for(int i = 30; i >= 0; i--)    {        int c = (v >> i) & 1;        if(!ch[u][c])        {            memset(ch[sz], 0, sizeof(ch[sz]));            val[sz] = 0;            ch[u][c] = sz++;        }        u = ch[u][c];        val[u] += d;    }}int match(int v){    int ans = 0, u = 0;    for(int i = 30; i >= 0; i--)    {        int c = (v >> i) & 1;        if(ch[u][c^1] && val[ch[u][c^1]])        {            ans |= (1 << i);            u = ch[u][c^1];        }        else            u = ch[u][c];    }    return ans;}int main(){    int n, T;    scanf("%d", &T);    while(T--)    {        init();        scanf("%d", &n);        for(int i = 1; i <= n; i++)        {            scanf("%d", &s[i]);            update(s[i], 1);        }        int ans = (s[1] + s[2]) ^ s[3];        for(int i = 1; i <= n; i++)        {            update(s[i], -1);            for(int j = i + 1; j <= n; j++)            {                update(s[j], -1);                int t = match(s[i] + s[j]);                ans = max(ans, t);                update(s[j], 1);            }            update(s[i], 1);        }        printf("%d\n", ans);    }    return 0;}


动态分配节点的写法:

#include<bits/stdc++.h>using namespace std;const int maxn = 1010;const int N = 2;int s[maxn];struct tree{    int val;    tree *nxt[N];    tree()    {        for(int i = 0; i < N; i++)            nxt[i] = NULL;        val = 0;    }}*root;int a[33];void ch(int x){    memset(a, 0, sizeof(a));    int len = 0;    while(x)    {        a[len++] = x % 2;        x /= 2;    }}void Insert(int x){    ch(x);    int len = 31;    tree *p = root;    while(len >= 0)    {        int id = a[len];        if(p -> nxt[id] == NULL)        {            tree *temp = new tree;            p -> nxt[id] = temp;        }        p = p -> nxt[id];        p -> val++;        len--;    }}int query(int x){    ch(x);    tree *p = root;    for(int i = 0; i < 31; i++)        a[i] ^= 1;    int len = 31;    int ans = 0;    while(len >= 0)    {        int id = a[len];        if(p -> nxt[id] == NULL || p -> nxt[id] -> val == 0)            id ^= 1;        if(id)            ans +=  1 << len;        p = p -> nxt[id];        len--;    }    return ans ^ x;}void del(int x){    ch(x);    int len = 31;    tree *p = root;    while(len >= 0)    {        int id = a[len];        p -> nxt[id] -> val--;        p = p -> nxt[id];        len--;    }}void fre(tree *tmp){    for(int i = 0; i < N; i++)        if(tmp -> nxt[i])            fre(tmp -> nxt[i]);    delete(tmp);}int main(){    int n, T;    scanf("%d", &T);    while(T--)    {        scanf("%d", &n);        root = new tree;        for(int i = 0; i < n; i++)        {            scanf("%d", &s[i]);            Insert(s[i]);        }        int ans = 0;        for(int i = 0; i < n; i++)        {            del(s[i]);            for(int j = i + 1; j < n; j++)            {                del(s[j]);                ans = max(ans, query(s[i] + s[j]));                Insert(s[j]);            }            Insert(s[i]);        }        printf("%d\n", ans);        fre(root);    }    return 0;}


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 两岁宝宝断奶不吃奶粉怎么办 宝宝断奶妈妈涨奶怎么办 三岁宝宝智商低怎么办 宝宝断奶晚上哭的厉害怎么办 2岁宝宝半夜喝奶粉怎么办 两岁宝宝不爱吃饭怎么办 快两岁的宝宝不爱吃饭怎么办 宝宝断奶后不愿意喝奶粉怎么办 宝宝断奶了不愿意喝奶怎么办? 宝宝断奶不愿意喝奶粉怎么办 宝宝断奶不愿意喝牛奶怎么办? 四个月宝宝断奶不吃奶粉怎么办 2岁不开口说话怎么办 八个月宝宝断奶不吃奶粉怎么办 宝宝断奶不喝奶粉怎么办 周岁 给娘家东西婆家看见怎么办 自己娘家妈总说婆家人坏话怎么办 娘家婆家老公都没有依靠怎么办? 2岁宝宝断奶粉怎么办 2岁宝宝夜奶频繁怎么办 宝宝15个月还在吃夜奶怎么办 宝宝两岁四个月还吃母乳怎么办 宝宝睡前老是找奶吃怎么办 宝宝戒奶晚上哭怎么办 宝宝戒奶半夜哭怎么办 吸习惯母乳不吸奶嘴怎么办 八个月宝宝奶睡怎么办 宝宝要吸着奶睡怎么办 戒母乳胸胀的疼怎么办 断奶孩子晚上哭的厉害怎么办 喜欢咬指甲的人怎么办? 成年了还咬指甲怎么办 戒奶乳房有硬块怎么办 戒奶七天有硬块怎么办 两岁宝宝喘气粗怎么办 两岁宝宝断不了奶怎么办 两岁宝宝不愿意喝奶粉怎么办 吃母乳不愿意吃奶粉怎么办 母乳宝宝不愿意喝奶粉怎么办 宝宝断母乳不喝奶粉怎么办 9个月宝宝不会爬怎么办