zoukankan      html  css  js  c++  java
  • 求序列完美度(trie+贪心)

    题目链接:

    求序列完美度

    题目描述

    给出由n个数组成的序列s,规定第i个数s[i]到第j个数s[j]组成的子序列的完美度为该子序列中所有数的和与任意一个不在该子序列中的数进行异或运算得到的值中的最大值,即perfect(s[i]~s[j])=max(sum(s[i]~s[j])^x),x为非子序列的数。现求完美度最大的子序列与它的完美度是多少

    输入

    第一行输入一个数T表示共有T组数据

    输入一个数n表示序列有n个数

    接下来有n个数,角标为1-n,表示序列的组成

    1<=T<=100

    3<=n<=1000

    0<=s[i]<=1000000

    输出

    输出四个数:i,j,x,perfect[s[i]~s[j]],分别表示完美度最大的子序列的左端点(1<=i<=n),右端点(i<=j<=n),x(参见题目描述)和序列的完美度(如有多组子序列完美度相同,输出左端点靠前的,若左端点相同输出右端点靠前的)

    样例输入

    2
    3
    1 2 3
    3
    1 3 2

    样例输出

    2 3 1 4
    1 2 2 6

    题意:

    思路:一个trie树,然后贪心就行,感觉题目描述有问题,还有数据范围有问题,看代码就知道了;

    AC代码:
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e3+10;
    int n,a[maxn];
    struct node
    {
        int l,r,x,mx;
    }ans;
    int ch[maxn*30][2],sz,val[maxn*30],vis[maxn*maxn];
    void insert(int x)
    {
        int u=0;
        for(int i=29;i>=0;i--)
        {
            int c=((x>>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]++;
        }
    }
    inline void del(int x)
    {
        int u=0;
        for(int i=29;i>=0;i--)
        {
            int c=((x>>i)&1);
            u=ch[u][c];
            val[u]--;
        }
    }
    int get_ans(int x)
    {
        int u=0,tep=0;
        for(int i=29;i>=0;i--)
        {
            int c=(((x>>i)&1)^1);
            if(val[ch[u][c]])u=ch[u][c],tep|=(1<<i);
            else u=ch[u][c^1];
        }
        return tep;
    }
    inline void init()
    {
        sz=1;memset(ch[0],0,sizeof(ch[0]));
        for(int i=1;i<=n;i++)insert(a[i]);
    }
    inline void solve(int p)
    {
        init();
        int sum=0;
        for(int i=p;i<=n;i++)
        {
            del(a[i]);
            sum+=a[i];
            int g=get_ans(sum);
            if(g>ans.mx)ans.mx=g,ans.l=p,ans.r=i,ans.x=sum^g;
            else if(g==ans.mx)
            {
                if(p<ans.l)ans.l=p,ans.r=i,ans.x=sum^g;
                else if(p==ans.l&&i<ans.r)ans.r=i,ans.x=sum^g;
            }
        }
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;i++)scanf("%d",&a[i]);
            ans.mx=-1;
            for(int i=1;i<=n;i++)solve(i);
            printf("%d %d %d %d
    ",ans.l,ans.r,ans.x,ans.mx);
        }
        return 0;
    }
    

      

  • 相关阅读:
    influxdb 使用
    【刷题】如何查找最长链
    学习中的开源框架和系统
    常见错误总结
    开发者必备网站
    计算机基础知识以及常用业务场景
    (1)、hive框架搭建和架构简介
    hadoop安装和配置
    linux基础
    UML学习目录
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/6965238.html
Copyright © 2011-2022 走看看