首页 > 其他分享 ># [THUSC2015] 异或运算

# [THUSC2015] 异或运算

时间:2024-12-25 21:43:32浏览次数:5  
标签:cnt ch 运算 int 异或 leq THUSC2015 now ig

P5795 [THUSC2015] 异或运算

题目描述

给定长度为 \(n\) 的数列 \(X={x_1,x_2,...,x_n}\) 和长度为 \(m\) 的数列 \(Y={y_1,y_2,...,y_m}\),令矩阵 \(A\) 中第 \(i\) 行第 \(j\) 列的值 \(A_{i,j}=x_i\ \operatorname{xor}\ y_j\),每次询问给定矩形区域 \(i∈[u,d],j∈[l,r]\),找出第 \(k\) 大的 \(A_{i,j}\)。

对于 \(100\%\) 的数据

  • \(0\leq X_i,Y_j<2^{31}\),
  • \(1\leq u\leq d\leq n\leq 1000\),
  • \(1\leq l\leq r\leq m\leq 300000\),
  • \(1\leq k\leq (d-u+1)\times (r-l+1)\), \(1\leq p\leq 500\)。

Solution:

我们发现数据范围十分的有意思,n,m及其的不对称,并且我们唯一能接受的多项式复杂度是 $ O(n \cdot q \cdot logm) $

我们维护一个可持久化 0/1 Trie,用来存每个b的值。然后对于每个查询,从31位开始往0位扫,在这个矩形中统计一下当前位 \(ig\) 为1的有多少,而统计的方式自然就是遍历 \(i \in [u,d]\) 查询对于每个 \(x_i\) ,假设它的第 \(ig\) 位是 \(now\)。我们需要统计在 $ -t[l-1]+t[r]$ 这颗树上,第 \(ig\) 位是 \(!now\) 的节点数

如果$ cnt \ge k$,说明这位必须取1,且将所有的主席树节点访问到 \(!now\) 如果不取的话那么排名至少为 \(cnt+1\) 。

如果 $cnt < k $,说明这位不能取1,但是在当前位 \(ig\) 有 \(cnt\) 个比 \(ans\) 大的数,所以在我们的主席树进入 \(now\) 统计答案之前要先将 \(k-=cnt\)

然后这题就做完了

Code:

#include<bits/stdc++.h>
const int N=3e5+5;
using namespace std;
int a[N],b[N];
struct Trie{
    int cnt;
    int rt[N],L[N],R[N];
    struct Tree{
        int ch[2],cnt;
    }t[N*50];
    inline void insert(int &x,int y,int val,int len)
    {
        t[x=++cnt]=t[y];
        t[x].cnt++;
        if(len<0)return ;
        int now=(val>>len)&1;
        insert(t[x].ch[now],t[y].ch[now],val,len-1);
    }
    int query(int x,int y,int l,int r,int k)
    {
        int res=0;
        for(int i=x;i<=y;i++)
        {
            L[i]=rt[l-1];
            R[i]=rt[r];
        }
        for(int ig=31;ig>=0;ig--)
        {
            int cnt=0;
            for(int i=x;i<=y;i++)
            {
                int now=(a[i]>>ig)&1;
                cnt+= -t[t[L[i]].ch[!now]].cnt+t[t[R[i]].ch[!now]].cnt;
            }
            if(cnt>=k)//这一位取1至少有 k 个 (这一位如果不取1,排名至少是cnt+1)
            {
                res|=(1<<ig);//这位要取1
                for(int i=x;i<=y;i++)
                {
                    int now=(a[i]>>ig)&1;
                    L[i]=t[L[i]].ch[!now];
                    R[i]=t[R[i]].ch[!now];
                }
            }
            else //这位不取1
            {
                k-=cnt;
                for(int i=x;i<=y;i++)
                {
                    int now=(a[i]>>ig)&1;
                    L[i]=t[L[i]].ch[now];
                    R[i]=t[R[i]].ch[now];
                }
            }
        }
        return res;
    }

}T;
int n,m,q;
void work()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&b[i]);
        T.insert(T.rt[i],T.rt[i-1],b[i],31);
    }
    cin>>q;
    for(int i=1,x,y,l,r,k;i<=q;i++)
    {
        scanf("%d%d%d%d%d",&x,&y,&l,&r,&k);
        int ans=T.query(x,y,l,r,k);
        printf("%d\n",ans);
    }
}
int main()
{
    //freopen("P5795_1.in","r",stdin);freopen("P5795.out","w",stdout);
    work();
    return 0;
}

标签:cnt,ch,运算,int,异或,leq,THUSC2015,now,ig
From: https://www.cnblogs.com/LG017/p/18631461

相关文章

  • Veilog学习笔记<2>语句运算符
    Veilog语句运算符:(1)算术运算符+:加法-:减法*:乘法/:除法%:取模(求余数)        eg :y=7%2 结果1  y=-7%2 结果-1            y=7%-2 结果1   y=-7%-2 结果-1   注:当进行求余运算时,结果的符号将与被除数(即第一个操作数)的符号相同。*......
  • 【深度学习基础|知识概述】基础数学和理论知识中的线性知识:矩阵与向量运算、特征值与
    【深度学习基础|知识概述】基础数学和理论知识中的线性知识:矩阵与向量运算、特征值与特征向量、张量,附代码。【深度学习基础|知识概述】基础数学和理论知识中的线性知识:矩阵与向量运算、特征值与特征向量、张量,附代码。文章目录【深度学习基础|知识概述】基础数学和理......
  • Java 变量和运算符
    Java变量和运算符1.变量(Variable)1.1何为变量1.2数据类型(DataTypes)1.2.1整型:byte、short、int、long1.2.2浮点类型:float、double1.2.3字符类型:char1.2.4布尔类型:boolean1.3变量的使用1.3.1步骤1:变量的声明1.3.2步骤2:变量的赋值1.4.基本数据类型变......
  • 华为机试:仿 LISP 运算 - Python实现
    华为机试:仿LISP运算_仿lisp运算华为机试-CSDN博客https://blog.csdn.net/weixin_44052055/article/details/125902077看到这一篇博文,感觉这个题目挺有意思的. 今天也做一个Python版本的.后面可能会逐步把它实现成一个Lisp解释器.importre#解析字符串(源代码),生成......
  • 运算符重载(一)
    知识图谱一.需要重载的原因正常情况下,C++的运算符(+、-、*、/等)只能用于对基本类型的常量或变量进行运算,而不能用于类对象之间的运算。类的对象直接的运算虽然可以通过成员函数或全局函数去实现,如date.Add(1),但这样的写法有时不易理解。C++的提供了重载运算符的特性,......
  • 3.5 图像与数值的运算
    参与运算的两个算子(参数)既可以是两幅图像,也可以是一幅图像与一个数值。例如,如果想增加图像的整体亮度,可以将每一个像素值都加上一个特定值。在具体实现时,可以给图像加上一个统一像素值的图像,也可以给图像加上一个固定值。【例3.12】演示图像与数值的运算结果。impor......
  • [THUSC2015] 异或运算 题解
    学到新思路了:求解\(k\)大值时,可以将所有元素放一块一起跑。考虑到\(n,q\)奇小无匹,我们便可以制造一个\(O(qn\logV)\)的代码。那么对于我们不想在时间复杂度中出现的\(m\),我们直接把他扔进可持久化\(Trie\)中销赃。再根据刚才那个思路,将\([u,d]\)中所有点扔进可持......
  • 运算符重载
    基本概念让类和结构体能够运用运算符关键字operator必须要是一个公共的静态方法,返回值要在operator前条件运算符需要成对实现,一个符号可以多个重载且不能使用ref和out基本语法//publicstatic返回类型operator运算符(参数列表)classPoint{publicintx;......
  • 三目运算符的使用
    Timing_Length=(Timing_Length==3)?0:Timing_Length++;在C语言(以及很多类似的编程语言中),三目运算符(?:)要求其第二和第三操作数(也就是?后面和:后面的表达式)是能返回一个确定值的常规表达式。在Timing_Length=(Timing_Length==3)?0:Timing_Length++;这个语句里,Ti......
  • 【Rust自学】6.3. 控制流运算符-match
    喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)6.3.1.什么是matchmatch允许一个值与一系列模式进行匹配,并执行匹配的模式对应的代码。模式可以是字面值、变量名、通配符等等。将match表达式想象为硬币分类机:硬币......