zoukankan      html  css  js  c++  java
  • LightOJ 1269 Consecutive Sum (Trie树)

    Jan's LightOJ :: Problem 1269 - Consecutive Sum

      题意是,求给定序列的中,子序列最大最小的抑或和。

      做法就是用一棵Trie树,记录数的每一位是0还是1。查询的时候,如果求最大值,就尽量让高位是1,相反就尽量让高位是0。

    代码如下,1y:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 
     6 using namespace std;
     7 
     8 const int N = 55555;
     9 const int M = 32;
    10 
    11 struct Node {
    12     int c[2];
    13     void init() { c[0] = c[1] = -1;}
    14 } ;
    15 
    16 struct Trie {
    17     Node node[M * N];
    18     int rt, curid;
    19     void init() { rt = curid = 0; node[curid++].init();}
    20     void insert(int x, int dg = 32) {
    21         int p = rt;
    22         for (int i = dg - 1, idx; i >= 0; i--) {
    23             idx = (x & 1 << i) != 0;
    24             if (node[p].c[idx] == -1) node[node[p].c[idx] = curid++].init();
    25             p = node[p].c[idx];
    26         }
    27     }
    28     int min(int x, int dg = 32) {
    29         int p = rt, ret = 0;
    30         for (int i = dg - 1, idx; i >= 0; i--) {
    31             idx = (x & 1 << i) != 0;
    32             if (~node[p].c[idx]) p = node[p].c[idx], ret <<= 1, ret |= idx;
    33             else p = node[p].c[!idx], ret <<= 1, ret |= !idx;
    34         }
    35         return ret;
    36     }
    37     int max(int x, int dg = 32) {
    38         int p = rt, ret = 0;
    39         for (int i = dg - 1, idx; i >= 0; i--) {
    40             idx = (x & 1 << i) == 0;
    41             if (~node[p].c[idx]) p = node[p].c[idx], ret <<= 1, ret |= idx;
    42             else p = node[p].c[!idx], ret <<= 1, ret |= !idx;
    43         }
    44         return ret;
    45     }
    46 } trie;
    47 
    48 int main() {
    49     int T, n, x;
    50     scanf("%d", &T);
    51     for (int cas = 1; cas <= T; cas++) {
    52         scanf("%d", &n);
    53         int ans1 = 0x80000000, ans2 = 0x7fffffff, sum = 0;
    54         trie.init();
    55         trie.insert(0);
    56         for (int i = 0; i < n; i++) {
    57             scanf("%d", &x);
    58             sum ^= x;
    59             //cout << sum << endl;
    60             ans1 = max(ans1, trie.max(sum) ^ sum);
    61             ans2 = min(ans2, trie.min(sum) ^ sum);
    62             trie.insert(sum);
    63         }
    64         printf("Case %d: %d %d
    ", cas, ans1, ans2);
    65     }
    66     return 0;
    67 }
    View Code

      其实做这题的时候想到一种比较麻烦的情况,那就是数里面有负数。这样的话需要对最高位特判,从而求得最大最小值。不过没有这样的数据,所以就不这么搞了。

    ——written by Lyon

  • 相关阅读:
    autorun.inf删除方法
    Re_Write序列号
    最常用的正则表达式
    SQL聚合使用GROUP BY
    Ext.Net的Window控件的简单使用
    SQL统计查询一个表中的记录,然后减法运算
    C#金额转换为汉字大写
    Ext.Net的Button按钮的使用
    C# 参考之方法参数关键字:params、ref及out 引用
    C#连接ACCESS 2007数据库
  • 原文地址:https://www.cnblogs.com/LyonLys/p/LOJ_1269_Lyon.html
Copyright © 2011-2022 走看看