• 计蒜客1264:求序列完美度(01字典树)


    传送门

    题意

    分析

    01字典树,每次插入所有数,按顺序删除查询,按题目要求更新答案即可
    学习了一种新的query写法

    trick

    1.不理解我的code的错误

    代码

    //wa
    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e3+10;//集合中的数字个数
    int ch[30*maxn][2];//节点的边信息
    int num[30*maxn];//记录节点的使用次数,删除时要用
    //int val[32*maxn];//节点存储的值
    int cnt;//树中节点的个数
    
    int t,n,ans,l,r,z;
    int a[1010];
    
    inline void init()
    {
        cnt=1;mem(ch[0],0);//清空树
    }
    
    void insert(int x)//在字典树中插入x,和一般字典树操作相同,将x化成二进制插入到字典树
    {
        int cur=0;
        for(int i=29;i>=0;--i)
        {
            int idx=((x>>i)&1);
            if(!ch[cur][idx])
            {
                mem(ch[cnt],0);
                num[cnt]=0;
                ch[cur][idx]=cnt++;
                //val[cnt++]=0;
            }
            //printf("ch[%d][%d]=%d
    ",cur,idx,ch[cur][idx]);
            cur=ch[cur][idx];
            num[cur]++;
        }
        //val[cur]=x;//最后节点插入val
    }
    
    void update(int x)
    {
        int cur=0;
        for(int i=29;i>=0;--i)
        {
            int idx=((x>>i)&1);
            cur=ch[cur][idx];
            num[cur]--;
        }
    }
    
    /*
    ll query(ll x)//在字典树(数集)中查找和x异或是最大值的元素y,返回y
    {
        int cur=0;
        for(int i=32;i>=0;--i)
        {
            int idx=(x>>i)&1;
            if(ch[cur][idx^1]) cur=ch[cur][idx^1];else cur=ch[cur][idx];
        }
        return val[cur];
    }
    */
    /*
    int query(int x)//在字典树(数集)中查找和x异或是最大值的元素y,返回异或的最大值
    //带删除操作的查询
    {
        int cur=0;
        for(int i=32;i>=0;--i)
        {
            int idx=(x>>i)&1;
            if(ch[cur][idx^1]&&num[ch[cur][idx^1]]) cur=ch[cur][idx^1];else cur=ch[cur][idx];
        }
        //printf("val(%d)=%d
    ",cur,val[cur]);
        return val[cur]^x;
    }
    */
    int get_ans(int x)
    {
        int cur=0,ret=0;
        for(int i=29;i>=0;--i)
        {
            int idx=(((x>>i)&1)^1);
            if(num[ch[cur][idx]]) cur=ch[cur][idx],ret|=(1<<i);
            else cur=ch[cur][idx^1];    
        }
        return ret;
    }
    void solve(int p)
    {
        init();
        F(i,1,n) insert(a[i]);
        int sum=0;
        F(i,p,n)
        {
            update(a[i]);
            sum+=a[i];
            int ret=get_ans(sum);
            if(ret>ans) ans=ret,l=p,r=i,z=sum^ret;
            else if(ret==ans)
            {
                if(p<l) l=p,r=i,z=sum^ret;
                else if(p==l&&i<r) r=i,z=sum^ret;
            }
        }
    }
    int main()
    {
        for(scanf("%d",&t);t--;)
        {
            scanf("%d",&n);
            F(i,1,n) scanf("%d",a+i);
            ans=-1;
            F(i,1,n) solve(i);
            printf("%d %d %d %d
    ",l,r,z,ans);
        }
        return 0;
    }
    
    //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];
    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;
    }
    
  • 相关阅读:
    Maven项目打包时指定配置策略
    使Jackson和Mybatis支持JSR310标准
    Java 8的Time包常用API
    MySQL 聚集拼接
    将List<E>内对象按照某个字段排序
    判断List<E>内是否有重复对象
    eclipse中Maven项目启动报错“3 字节的 UTF-8 序列的字节 3 无效。”
    控制层@Value注解取不到值
    IntelliJ IDEA实时代码模板
    OD: Exploit Me
  • 原文地址:https://www.cnblogs.com/chendl111/p/7132961.html
Copyright © 2020-2023  润新知