bzoj4546-codechef XRQRS(可持久化Trie)

中文题题意我就不说了

解析: 可持久化Trie的模板题,详见注释

代码

#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxbit=19;
const int maxn=10500005;
int tr[500002];
struct PerTrie
{
    int id;
    int next[maxn][2],num[maxn];
    void init(){ id=next[0][0]=next[0][1]=num[0]=0; }//初始化
    int f(int x,int i){ return (x>>i)&1; } //判断x的第i位为0或1
    void Insert(int& rt,int pre,int x,int pos) //插入
    {
        rt=++id;
        next[rt][0]=next[pre][0]; //赋等
        next[rt][1]=next[pre][1];
        num[rt]=num[pre]+1; //数量加1
        if(pos==-1) return;
        int d=f(x,pos);
        Insert(next[rt][d],next[pre][d],x,pos-1);
    }
    int MaxXor(int l,int r,int x)
    {
        int ret=0;
        for(int i=maxbit;i>=0;i--)
        {
            int d=f(x,i);
            int a=next[l][d^1],b=next[r][d^1];
            if(num[b]-num[a]>0) ret|=(1<<i),l=a,r=b; //判断是否存在
            else l=next[l][d],r=next[r][d];
        }
        return ret;
    }
    int MinNum(int l,int r,int x)
    {
        int ret=0;
        for(int i=maxbit;i>=0;i--)
        {
            int d=f(x,i);
            if(d) ret+=num[next[r][0]]-num[next[l][0]]; //比它小的加上
            l=next[l][d]; r=next[r][d];
        }
        ret+=num[r]-num[l];  //<=要加上它,<的话就不用了
        return ret;
    }
    int Kth(int l,int r,int k)
    {
        int ret=0;
        for(int i=maxbit;i>=0;i--)
        {
            int t=num[next[r][0]]-num[next[l][0]];
            if(t>=k) l=next[l][0],r=next[r][0];  //足够
            else ret|=(1<<i),l=next[l][1],r=next[r][1],k-=t;
        }
        return ret;
    }
}PT;
int main()
{
    int Q;
    scanf("%d",&Q);
    int type,l,r,x,cnt=0;
    tr[0]=0;
    PT.init();
    while(Q--)
    {
        scanf("%d",&type);
        if(type==1)
        {
            scanf("%d",&x);
            ++cnt;
            PT.Insert(tr[cnt],tr[cnt-1],x,maxbit); //插入新的值
        }
        else if(type==2)
        {
            scanf("%d%d%d",&l,&r,&x);
            printf("%d\n",PT.MaxXor(tr[l-1],tr[r],x)^x);
        }
        else if(type==3)
        {
            scanf("%d",&x);
            cnt-=x;
        }
        else if(type==4)
        {
            scanf("%d%d%d",&l,&r,&x);
            printf("%d\n",PT.MinNum(tr[l-1],tr[r],x));
        }
        else
        {
            scanf("%d%d%d",&l,&r,&x);
            printf("%d\n",PT.Kth(tr[l-1],tr[r],x));
        }
    }
    return 0;
}

时间: 2024-12-21 18:22:32

bzoj4546-codechef XRQRS(可持久化Trie)的相关文章

【BZOJ4260】 Codechef REBXOR 可持久化Trie

看到异或就去想前缀和(⊙o⊙) 这个就是正反做一遍最大异或和更新答案 最大异或就是很经典的可持久化Trie,从高到低贪心 WA: val&(1<<(base-1))得到的并不直接是1/0 1 #include<bits/stdc++.h> 2 #define ll long long 3 #define N 400005 4 using namespace std; 5 inline int read(){ 6 int x=0,f=1;char ch=getchar();

bzoj4546 codechef XRQRS

Description 给定一个初始时为空的整数序列(元素由1开始标号)以及一些询问: 类型1:在数组后面就加入数字x. 类型2:在区间L…R中找到y,最大化(x xor y). 类型3:删除数组最后K个元素. 类型4:在区间L…R中,统计小于等于x的元素个数. 类型5:在区间L…R中,找到第k小的数. Input 输入数据第一行为一个整数q,表示询问个数,接下来q行,每行一条询问 对应题目描述. 类型1的询问格式为“1 x”. 类型2的询问格式为“2 L R x”. 类型3的询问格式为“3 k

【BZOJ2741】【块状链表+可持久化trie】FOTILE模拟赛L

Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 ... xor Aj),其中l<=i<=j<=r. 为了体现在线操作,对于一个询问(x,y): l = min ( ((x+lastans) mod N)+1 , ((y+lastans) mod N)+1 ).r = max ( ((x+lastans) mod N)+1 , ((y+last

bzoj4103异或运算 可持久化trie树

要去清华冬令营了,没找到2016年的题,就先坐一坐15年的. 因为n很小,就按照b串建可持久化trie树,a串暴力枚举. 其他的直接看代码. #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; inline int read() { int x=0,f=1,ch=getchar(); while(ch<'0'||ch

BZOJ 3261: 最大异或和 [可持久化Trie]

3261: 最大异或和 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1513  Solved: 657[Submit][Status][Discuss] Description 给定一个非负整数序列 {a},初始长度为 N.       有   M个操作,有以下两种操作类型: 1 .A x:添加操作,表示在序列末尾添加一个数 x,序列的长度 N+1.2 .Q l r x:询问操作,你需要找到一个位置 p,满足 l<=p<=r,使得: a[p]

bzoj 2741: 【FOTILE模拟赛】L 分塊+可持久化trie

2741: [FOTILE模拟赛]L Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1116  Solved: 292[Submit][Status] Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 ... xor Aj),其中l<=i<=j<=r. 为了体现在线操作,对于一个询问(x,y):

[您有新的未分配科技点]可,可,可持久化!?------0-1Trie和可持久化Trie普及版讲解

这一次,我们来了解普通Trie树的变种:0-1Trie以及在其基础上产生的可持久化Trie(其实,普通的Trie也可以可持久化,只是不太常见) 先简单介绍一下0-1Trie:一个0-1Trie节点只有两个子节点,分别代表0和1:从根节点开始,第一层代表限制的最高位,依次往下直到最底层,代表二进制第0位. 0-1Trie上的一条链所表示的数字,就是Trie树中的一个数字.0-1Trie除了节点和插入方式与普通的Trie树略有不同之外,其他操作都是和Trie树完全一样的.在维护这个节点插入过的siz

【bzoj4212】神牛的养成计划 Trie树+可持久化Trie树

题目描述 Hzwer成功培育出神牛细胞,可最终培育出的生物体却让他大失所望...... 后来,他从某同校女神 牛处知道,原来他培育的细胞发生了基因突变,原先决定神牛特征的基因序列都被破坏了,神牛hzwer很生气,但他知道基因突变的低频性,说不定还有以下优秀基因没有突变,那么他就可以用限制性核酸内切酶把它们切出来,然后再构建基因表达载体什么的,后面你懂的...... 黄学长现在知道了N个细胞的DNA序列,它们是若干个由小写字母组成的字符串.一个优秀的基因是两个字符串s1和s2,当且仅当s1是某序列

【bzoj3281】最大异或和 可持久化Trie树

题目描述 给定一个非负整数序列 {a},初始长度为 N.       有M个操作,有以下两种操作类型:1.A x:添加操作,表示在序列末尾添加一个数 x,序列的长度 N+1.2.Q l r x:询问操作,你需要找到一个位置 p,满足 l<=p<=r,使得:a[p] xor a[p+1] xor ... xor a[N] xor x 最大,输出最大是多少. 输入 第一行包含两个整数 N  ,M,含义如问题描述所示.   第二行包含 N个非负整数,表示初始的序列 A . 接下来 M行,每行描述一个