• 1269


    1269 - Consecutive Sum
    Time Limit: 3 second(s) Memory Limit: 64 MB

    Little Jimmy is learning how to add integers. As in decimal the digits are 0 to 9, it makes a bit hard for him to understand the summation of all pair of digits. Since addition of numbers requires the knowledge of adding digits. So, his mother gave him a software that can convert a decimal integer to its binary and a binary to its corresponding decimal. So, Jimmy's idea is to convert the numbers into binaries, and then he adds them and turns the result back to decimal using the software. It's easy to add in binary, since you only need to know how to add (0, 0), (0, 1), (1, 0), (1, 1). Jimmy doesn't have the idea of carry operation, so he thinks that

    1 + 1 = 0

    1 + 0 = 1

    0 + 1 = 1

    0 + 0 = 0

    Using these operations, he adds the numbers in binary. So, according to his calculations,

    3 (011) + 7 (111) = 4 (100)

    Now you are given an array of n integers, indexed from 0 to n-1, you have to find two indices i j in the array (0 ≤ i ≤ j < n), such that the summation (according to Jimmy) of all integers between indices i and jin the array, is maximum. And you also have to find two indices, p q in the array (0 ≤ p ≤ q < n), such that the summation (according to Jimmy) of all integers between indices p and in the array, is minimum. You only have to report the maximum and minimum integers.

    Input

    Input starts with an integer T (≤ 10), denoting the number of test cases.

    Each case starts with a line containing an integer n (1 ≤ n ≤ 50000). The next line contains n space separated non-negative integers, denoting the integers of the given array. Each integer fits into a 32 bit signed integer.

    Output

    For each case, print the case number, the maximum and minimum summation that can be made using Jimmy's addition.

    Sample Input

    Output for Sample Input

    2

    5

    6 8 2 4 2

    5

    3 8 2 6 5

    Case 1: 14 2

    Case 2: 15 1

    Note

    Dataset is huge, use faster I/O methods.

    题意:求连续区间的异或的最大和最小值;

    思路:trie树,贪心;

    先求一遍前缀异或和;然后先将0加入tire树,0异或任何值为那个值本身,然后我们知道pre[i]^pre[j];j<i;

    ans[j+1]^ans[j+2]...^ans[i];也就是区间[i,j],那么我们把前面的前缀加入tire,然后我们在树中贪心选取,如果是找最大的,就贪心选与当前位不同的,因为是按最高位

    依次往下,所以我们保证高位数要尽量大,如果不存在与当前位相同,那么只能走相同的。知道咋贪心最大的,最小的和这差不多。

    复杂度为(n*log(1<<31-1));

      1 #include<stdio.h>
      2 #include<algorithm>
      3 #include<string.h>
      4 #include<stdlib.h>
      5 #include<iostream>
      6 using namespace std;
      7 typedef long long LL;
      8 LL ans[500005];
      9 int id[32];
     10 struct node
     11 {
     12     node *p[2];
     13     node()
     14     {
     15         memset(p,0,sizeof(p));
     16     }
     17 };
     18 node *root;
     19 void in(int *v)
     20 {
     21     int i,j,k;
     22     node *c=root;
     23     for(i=30; i>=0; i--)
     24     {
     25         int pre=v[i];
     26         if(c->p[v[i]]==NULL)
     27         {
     28             c->p[v[i]]=new node();
     29         }
     30         c=c->p[v[i]];
     31     }
     32 }
     33 LL ma(int *v)
     34 {
     35     LL sum=0;
     36     LL l=1;
     37     node*c=root;
     38     int i;
     39     for(i=30; i>=0; i--)
     40     {
     41         int pre=v[i];
     42         if(c->p[(pre+1)%2]==NULL)
     43         {
     44             c=c->p[pre];
     45             sum*=2;
     46             sum+=0;
     47         }
     48         else
     49         {
     50             c=c->p[(pre+1)%2];
     51             sum*=2;
     52             sum+=1;
     53         }
     54     }
     55     return sum;
     56 }
     57 LL mi(int *v)
     58 {
     59     LL sum=0;
     60     LL l=2;
     61     node*c=root;
     62     int i;
     63     for(i=30; i>=0; i--)
     64     {
     65         int pre=v[i];
     66         if(c->p[pre]==NULL)
     67         {
     68             c=c->p[(pre+1)%2];
     69             sum*=2;
     70             sum+=1;
     71         }
     72         else
     73         {
     74             c=c->p[pre];
     75             sum*=2;
     76             sum+=0;
     77         }
     78     }
     79     return sum;
     80 }
     81 void del(node *c)
     82 {
     83     for(int i=0; i<2; i++)
     84     {
     85         if(c->p[i]!=NULL)
     86             del(c->p[i]);
     87     }
     88     free(c);
     89 }
     90 int main(void)
     91 {
     92     int i,j,k;
     93     scanf("%d",&k);
     94     int s;
     95     int n,m;
     96     for(s=1; s<=k; s++)
     97     {
     98         scanf("%d",&n);
     99         for(i=1; i<=n; i++)
    100         {
    101             scanf("%lld",&ans[i]);
    102             ans[i]^=ans[i-1];
    103         }
    104         root=new node();
    105         LL maxx=0;
    106         LL minn=1e12;
    107         memset(id,0,sizeof(id));
    108         in(id);
    109         for(i=1; i<=n; i++)
    110         {
    111             memset(id,0,sizeof(id));
    112             LL kk=ans[i];
    113             int cnt=0;
    114             while(kk)
    115             {
    116                 id[cnt++]=kk%2;
    117                 kk/=2;
    118             }
    119             maxx=max(maxx,ma(id));
    120             minn=min(minn,mi(id));
    121             in(id);
    122         }del(root);
    123         printf("Case %d: ",s);
    124         printf("%lld %lld
    ",maxx,minn);
    125     }return 0;
    126 }
    油!油!you@
  • 相关阅读:
    [置顶] 内外网同时访问,我的拿来主义
    Nginx防攻击工具教程一 ngx_http_limit_conn_module
    晒晒我的厨艺修炼成果
    在 javascript 中,为什么 [1,2] + [3,4] 不等于 [1,2,3,4]?
    无法解析的外部符号__imp__AlphaBlend@44的解决
    Win32 API实现CDC类的FillSolidRect接口
    pugixml库学习之添加节点
    cleanup failed because the file not under version control问题的解决
    JavaScript 的 typeof 的用途
    支持在Win7和XP系统上创建环境变量的批处理文件
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5484182.html
Copyright © 2020-2023  润新知