hdu 5536 Chip Factory 2015长春区域赛 数据结构 Trie

题目

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5536

题目来源:2015长春区域赛。

简要题意:求 maxi,j,k{(si+sj)sk} i,j,k 互异。

数据范围: 1T1000;3n1000;0si109

题解

现场听说三方大暴力能过,hdoj机子弱或者改了数据所以要用数据结构。

题意很简单易懂,主要是异或搞的时候可以用Trie来贪心搞,降低复杂度

假如Trie是从前往后建的,则高位为 1 是最好的,于是只要走32层就能得到答案。

具体来说就是 sk 去建Trie,然后枚举 i,j 的组合,查询的时候去除 si,sj 查询完后再加上

实现

如果考虑建 si+sj 的Trie,空间复杂度会过高。

实现可以用递归或者非递归的,后者会更快一点。

这是第一次写Trie,成功1A,但是看了学长代码觉得有点挫了,然后改了下。

原来的版本通用性有点差,然后性能也不够好,在此给出两个版本。

递归版本代码

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>

#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
// head
const int ST = 31;
const int MX_NODE = 3.5e4;

struct Node {
    int l, r, v;
    void clr() {
        l = r = v = 0;
    }
};

struct Trie {
    Trie() {cnt = 0;}
    int cnt;

    int build(int cur, int c, int pos) {
        bool isr = (1<<pos)&c;
        node[cur].v++;
        if (pos == -1) return cur;
        int nxt;
        if (isr) {
            if (!node[cur].r) node[cur].r = getNewNode();
            nxt = node[cur].r;
        } else {
            if (!node[cur].l) node[cur].l = getNewNode();
            nxt = node[cur].l;
        }
        build(nxt, c, pos-1);
    }

    void del(int cur, int c, int pos) {
        bool isr = (1<<pos)&c;
        node[cur].v--;
        if (pos == -1) return;
        int nxt = isr ? node[cur].r : node[cur].l;
        del(nxt, c, pos-1);
    }

    int getMaxXor(int cur, int c, int pos) {
        if (node[cur].v == 0) return -1;
        if (pos == -1) return 0;
        bool isl = (1<<pos)&c;
        int res, ans;
        if (isl) {
            res = node[cur].l == 0 ? -1 : getMaxXor(node[cur].l, c, pos-1);
            ans = (res == -1) ? getMaxXor(node[cur].r, c, pos-1) : res + (1<<pos);
        } else {
            res = node[cur].r == 0 ? -1 : getMaxXor(node[cur].r, c, pos-1);
            ans = (res == -1) ? getMaxXor(node[cur].l, c, pos-1) : res + (1<<pos);
        }
        return ans;
    }

    int getNewNode() {
        node[++cnt].clr();
        return cnt;
    }

    void init() {
        cnt = 0;
        node[0].clr();
    }

    Node node[MX_NODE];
};

Trie trie;
int a[1005];

int main()
{
    int t, n;
    scanf("%d", &t);
    while (t--) {
        scanf("%d", &n);
        trie.init();

        for (int i = 0; i < n; i++) {
            scanf("%d", a+i);
            trie.build(0, a[i], ST);
        }

        int ans = 0;
        for (int i = 0; i < n; i++) {
            trie.del(0, a[i], ST);
            for (int j = i+1; j < n; j++) {
                trie.del(0, a[j], ST);
                ans = max(ans, trie.getMaxXor(0, a[i]+a[j], ST));
                trie.build(0, a[j], ST);
            }
            trie.build(0, a[i], ST);
        }
        printf("%d\n", ans);
    }
    return 0;
}

非递归版本代码

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>

#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
// head
const int ST = 31;
const int MX_NODE = 3.5e4;
const int CHARSET = 2;

struct Node {
    int v;
    int p[CHARSET];
    void clr() {
        v = 0;
        for (int i = 0; i < CHARSET; i++) p[i] = 0;
    }
    inline int get(int x) {
        return p[x];
    }
    inline void set(int x, int v) {
        p[x] = v;
    }
};

struct Trie {
    Trie() {cnt = 0;}
    int cnt;

    int build(int c) {
        int cur = 0, bit;
        for (int i = ST; i > -1; i--) {
            Node &x = node[cur];
            bit = (c>>i)&1;
            if (!x.get(bit)) x.set(bit, getNewNode());
            cur = x.get(bit);
            node[cur].v++;
        }
    }

    void del(int c) {
        int cur = 0, bit;
        for (int i = ST; i > -1; i--) {
            bit = (c>>i)&1;
            cur = node[cur].get(bit);
            node[cur].v--;
        }
    }

    int getMaxXor(int c) {
        int cur = 0, ans = -1, bit, nxt;
        for (int i = ST; i > -1; i--) {
            Node &x = node[cur];
            bit = ((c>>i)&1)^1;
            if (!node[x.get(bit)].v) bit ^= 1, ans ^= (1<<i);
            cur = x.get(bit);
        }
        return ans;
    }

    int getNewNode() {
        node[++cnt].clr();
        return cnt;
    }

    void init() {
        cnt = 0;
        node[0].clr();
    }
    Node node[MX_NODE];
};

Trie trie;
int a[1005];

int main()
{
    int t, n;
    scanf("%d", &t);
    while (t--) {
        scanf("%d", &n);
        trie.init();

        for (int i = 0; i < n; i++) {
            scanf("%d", a+i);
            trie.build(a[i]);
        }

        int ans = 0;
        for (int i = 0; i < n; i++) {
            trie.del(a[i]);
            for (int j = i+1; j < n; j++) {
                trie.del(a[j]);
                ans = max(ans, trie.getMaxXor(a[i]+a[j]));
                trie.build(a[j]);
            }
            trie.build(a[i]);
        }
        printf("%d\n", ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值