HDU-2017 多校训练赛3-1004-Kanade's trio

来源:互联网 发布:华为盒子看电影软件 编辑:程序博客网 时间:2024/06/17 18:39

ACM模版

描述

描述

题解

这个题思路十分巧妙,没想到竟然可以用字母树解。

描述

题解不难理解,就是有些出人意料了。看了题解后,我拿着官方题解,参考着写了一份,习惯性的将一些东西改成了自己的习惯……比如说,初始化能用 memset() 的都用 memset(),然后我就超时了……,很纳闷儿,再三斟酌,我尝试将初始化改成了循环初始化,发现一下子竟然 AC 了。这是最让我十分意外的,我一直以来都十分认可 memset(),以为他会快很多,但是,他并没有想象中那么快。之所以会超时是因为循环初始化人家用多少初始化多少,而 memset() 我则是习惯性的将整个数组初始化,导致时间消耗一下子上去了,题中有个很重要的条件,1n5105,所以,这里并没有直接给 n 的范围,为了肯定可行,我们都是开了足够大,但是我们绝大多数空间都是用不到的,如果每次都是 memset() 整个数组,自然是浪费太严重,时间消耗太高,TLE 也就正常了。

所以呢,以后一定要注意 memset() 函数的用处,并不能因为他效率高,而一味的简易处理,代码虽然简单了,TLE 也是没商量的事。

代码

#include <iostream>#include <cstdio>using namespace std;typedef long long ll;const int MAXN = 5e5 + 10;const int MAGIC = 30;template <class T>inline void scan_d(T &ret){    char c;    ret = 0;    while ((c = getchar()) < '0' || c > '9');    while (c >= '0' && c <= '9')    {        ret = ret * 10 + (c - '0'), c = getchar();    }}int n, tot;int a[MAXN];int go[MAXN << 5][2];int num[MAXN << 5];int tree[MAXN][MAGIC][2];ll ss[MAXN << 5];int main(){    int T;    scan_d(T);    while (T--)    {        for (int i = 1; i <= tot; i++)        {            go[i][0] = go[i][1] = 0;            ss[i] = num[i] = 0;        }        for (int i = 1; i <= n; i++)        {            for (int j = 0; j < MAGIC; j++)            {                tree[i][j][0] = tree[i][j][1] = 0;            }        }        tot = 1;        scan_d(n);        for (int i = 1; i <= n; i++)        {            scan_d(a[i]);        }        for (int i = 1; i <= n; i++)        {            for (int j = 0; j < MAGIC; j++)            {                tree[i][j][0] = tree[i - 1][j][0];                tree[i][j][1] = tree[i - 1][j][1];            }            for (int j = 0; j < MAGIC; j++)            {                int k = (a[i] & (1 << j)) > 0;                tree[i][j][k]++;            }        }        ll ans = 0;        for (int i = n; i >= 1; i--)        {            int now = 1;            for (int j = MAGIC - 1; j >= 0; j--)            {                int k = (a[i] & (1 << j)) > 0;                if (go[now][k ^ 1])                {                    ans += ss[go[now][k ^ 1]] - num[go[now][k ^ 1]] * 1ll * tree[i][j][k];                }                if (!go[now][k])                {                    break;                }                now = go[now][k];            }            now = 1;            for (int j = MAGIC - 1; j >= 0; j--)            {                int k = (a[i] & (1 << j)) > 0;                if (!go[now][k])                {                    go[now][k] = ++tot;                }                now = go[now][k];                ss[now] += tree[i - 1][j][k ^ 1];                num[now]++;            }        }        cout << ans << endl;    }    return 0;}
原创粉丝点击