【BZOJ4103】【Thusc2015】异或运算 可持久Trie

原创 2016年06月01日 11:08:08

现在再来切是不是有点晚QAQ

题目大意是给定两个正整数序列。规定矩阵(异或运算),每个询问求某个子矩阵内第k大的值。其中

注意到N和Q比较小,所以就是把序列B建成可持久Trie,然后同时跑A中的若干个数。。。

如果想不清楚可以先考虑当N=1,也就是A是一个数的情况,然后再考虑如何合并。

/**************************************************************
    Problem: 4103
    User: cqyzhb
    Language: C++
    Result: Accepted
    Time:5364 ms
    Memory:126804 kb
****************************************************************/
 
#include<cstdlib>
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define MAXN 300005
void _read(int &x)
{
    x=0; char ch=getchar(); bool flag=false;
    while(ch<'0' || ch>'9'){if(ch=='-')flag=true; ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} if(flag)x=-x; return ;
}
int N,M,A[1005],B[MAXN],sum[32][1005],np;
int chi[MAXN*35][2],sz[MAXN*35],rt[MAXN];
void Insert(int anc,int &rt,int x)
{
    rt=++np; int now=np; sz[now]=sz[anc]+1;;
    for(int i=30;i>=0;i--)
    {
        if((1<<i)&x)
        {
            chi[now][0]=chi[anc][0]; chi[now][1]=++np; sz[chi[now][1]]=sz[chi[anc][1]]+1; 
            now=chi[now][1]; anc=chi[anc][1];
        }
        else
        {
            chi[now][1]=chi[anc][1]; chi[now][0]=++np; sz[chi[now][0]]=sz[chi[anc][0]]+1; 
            now=chi[now][0]; anc=chi[anc][0];
        }
    }
    return ;
}
void Init()
{
    _read(N);_read(M);
    for(int i=1;i<=N;i++)_read(A[i]); for(int i=1;i<=M;i++)_read(B[i]);
    rt[0]=0; np=0; sz[0]=0;
    for(int i=1;i<=M;i++)Insert(rt[i-1],rt[i],B[i]);
    for(int i=0;i<=30;i++)
    {
        sum[i][0]=0;
        for(int j=1;j<=N;j++)
        {
            if(A[j]&(1<<i))sum[i][j]=sum[i][j-1]+1;
            else sum[i][j]=sum[i][j-1];
        }
    }
    return ;
}
int tmp[1005][2];
void query(int anc,int now,int L,int R,int k)
{
    int ct=0,t=0,ans=0;
    for(int i=L;i<=R;i++)
    {
        tmp[i][0]=anc; tmp[i][1]=now;
    }
    for(int i=30;i>=0;i--)
    {
        t=0;
        for(int j=L;j<=R;j++)
        {
            if(A[j]&(1<<i))
            {
                t+=sz[chi[tmp[j][1]][1]]-sz[chi[tmp[j][0]][1]];
            }
            else
            {
                t+=sz[chi[tmp[j][1]][0]]-sz[chi[tmp[j][0]][0]];
            }
        }
        if(ct+t>=k) // 答案的这一位是0
        {
            for(int j=L;j<=R;j++)
            {
                if(A[j]&(1<<i)) // 向1那边走 
                {
                    tmp[j][0]=chi[tmp[j][0]][1];tmp[j][1]=chi[tmp[j][1]][1];
                }
                else
                {
                    tmp[j][0]=chi[tmp[j][0]][0];tmp[j][1]=chi[tmp[j][1]][0];
                }
            }           
        }
        else // 1
        {
            ans+=(1<<i); ct+=t;
            for(int j=L;j<=R;j++)
            {
                if(A[j]&(1<<i)) // 向0那边走 
                {
                    tmp[j][0]=chi[tmp[j][0]][0];tmp[j][1]=chi[tmp[j][1]][0];
                }
                else
                {
                    tmp[j][0]=chi[tmp[j][0]][1];tmp[j][1]=chi[tmp[j][1]][1];
                }
            }
        }
    }
    printf("%d\n",ans);
    return ;
}
void work()
{
    int u,d,l,r,k,Q;
    _read(Q);
    for(int i=1;i<=Q;i++)
    {
        _read(u); _read(d); _read(l); _read(r); _read(k); k=(d-u+1)*(r-l+1)+1-k;
        query(rt[l-1],rt[r],u,d,k);     
    }
    return ;
}
int main()
{
//  freopen("in.txt","r",stdin);
    Init();
    work();
    return 0;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

bzoj4103【THUSC2015】异或运算

可持久化Trie树
  • AaronGZK
  • AaronGZK
  • 2016年06月01日 00:27
  • 3044

【BZOJ4103】异或运算(THUSC2015)-可持久化trie树+位运算

【BZOJ4103】异或运算(THUSC2015)-可持久化trie树+位运算
  • Maxwei_wzj
  • Maxwei_wzj
  • 2017年05月18日 19:34
  • 182

BZOJ 3261 浅谈可持久化TRIE树最大连续异或和

世界真的很大 trie树贪心求最大异或和大概也就是那么回事了 但是对于区间的查询就不是那么容易的了 考虑主席树的思想,怎么得到区间的值域的 这就是可持久化的trie树 说来容易 指针教做人...
  • BerryKanry
  • BerryKanry
  • 2017年07月26日 20:34
  • 462

【bzoj4103】 【Thu Summer Camp 2015】【异或运算】【可持久化trie】

Description 给定长度为n的数列X={x1,x2,...,xn}和长度为m的数列Y={y1,y2,...,ym},令矩阵A中第i行第j列的值Aij=xi xor  yj,每次询问给定矩...
  • sunshinezff
  • sunshinezff
  • 2016年05月31日 17:03
  • 278

【BZOJ4546】codechef XRQRS【可持久化Trie / +主席树】

【题目链接】 早上刚在CC上做了,中午就被人搬到BZOJ了。。 不知道为什么n开50wRE,开了52w卡了下内存就过了。 【CC上这题题解】 /* Pigonometry */ #in...
  • BraketBN
  • BraketBN
  • 2016年04月22日 14:57
  • 538

BZOJ 3261 最大异或和 可持久化Trie树

题目大意:给定一个序列,提供下列操作: 1.在数组结尾插入一个数 2.给定l,r,x,求一个l 首先我们可以维护前缀和 然后就是使x^sum[n]^sum[p-1]最大 x^sum[n]为定值...
  • PoPoQQQ
  • PoPoQQQ
  • 2014年10月14日 09:46
  • 2095

【CodeChef-XRQRS】Xor Queries【可持久化Trie / +主席树】

【题目链接】 有中文题面就不发题意了。 似乎维护一个可持久化Trie和一个主席树就可以做了,但是仔细想想好像只需要一个可持久化Trie就完了。 脑补了一下Trie上找第k大和统计数个数,似乎...
  • BraketBN
  • BraketBN
  • 2016年04月22日 08:27
  • 503

按位与、或、异或运算

一、按位与(&) 1、概念:参加运算的两个对象,按二进制位进行“与”运算,负数按补码形式参加按位与运算。 2、运算规则:0&0=0; 0&1=0;1&0=0;1&1=1;即:两位同时为“1”,结果才为...
  • u012050154
  • u012050154
  • 2016年07月19日 17:18
  • 8820

异或运算的神奇运用

转自:http://www.physixfan.com/archives/563/Xor运算是位运算的一种,和And、Or运算类似,假如a、b都是布尔变量,则a Xor b被定义为:a、b相异则为真(...
  • Dustin_CDS
  • Dustin_CDS
  • 2016年03月05日 13:05
  • 832

异或运算的作用

参与运算的两个值,如果两个相应bit位相同,则结果为0,否则为1。 即:    0^0 = 0,        1^0 = 1,        0^1 = 1,        1^1 = 0...
  • gtkknd
  • gtkknd
  • 2016年10月12日 16:39
  • 3280
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【BZOJ4103】【Thusc2015】异或运算 可持久Trie
举报原因:
原因补充:

(最多只允许输入30个字)