首页 > 其他分享 >处理异或运算下的不等式

处理异或运算下的不等式

时间:2024-10-24 12:43:17浏览次数:3  
标签:ch 运算 不等式 int ret trie 异或 cx

真的恶心,妈的放道D1恶心人,D1跟D2正解毛关系都没有,傻逼比赛

题号 CF1720D2 Xor-Subsequence (hard version)

简单转化一下题意就是求这样的一个 dp 数组:
\(f[i]=max_{a[i]⊕j>a[j]⊕i}(f[j]+1)\)

以前看见异或不等完全不敢在不等号两边操作,然后这题就是要在不等号上操作:

  • 先考虑对这个不等式变换,先把 \(i,j\) 分离,这是个常用套路:
  • 变成 \((x[i]=a[i]⊕i)⊕(i⊕j)>(x[j]=a[j]⊕j)⊕(i⊕j)\),这样式子的运算本质上就被统一了(感性理解一下,因为左右两边同时异或上一个相等的数),然后考虑怎么去除 \((i⊕j)\)

考虑模拟二进制比较,就是先求出 \(x⊕y\) 的值,看看在最高位的 \(1\) 上谁大谁小。那么假如我原先知道 \(x,y\) 的大小关系、他们最高在哪一位不同,那么如果我同时给 \(x,y\) 异或的数 \(t\) 在那位的值为 \(1\) 那么大小关系反转,反之亦然,那么我就可以枚举 \(x[i],x[j]\) 在哪一位是不同的,这个可以放在 01trie 上搞,假如我枚举到第 \(k\) 位是不同的,那么我本质上只关心这些 这棵子树中有多少 \(j\) 异或上 \(i\) 后第 \(k\) 位为 \(0/1\) ,这些 \(j\) 的最大值是多少,由于我只关心这一位,和别的位毛关心都没有,那么我直接在 01trie 树上多记一个 tag 来将这棵子树中的 \(j\) 按照这一位的 \(0/1\) 来分类,然后就差不多了。

#include <bits/stdc++.h>
using namespace std;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch))f^=ch=='-',ch=getchar();
    while(isdigit(ch))x=x*10+(ch^48),ch=getchar();
    return f?x:-x;
}
const int N=3e5+5,C=60,_log=30;
int trie[N*C][2],val[N*C][2],f[N],n,pool,ans;
void clear(){
    for(int i=1;i<=pool;++i){
        trie[i][0]=trie[i][1]=0;
        val[i][0]=val[i][1]=0;
    }
    pool=1;
}
void modify(int x,int y,int df){
    int p=1;
    for(int i=_log;i>=0;--i){
        int cx=(x>>i)&1,cy=(y>>i)&1;
        if(!trie[p][cx])trie[p][cx]=++pool;
        val[trie[p][cx]][cy]=max(val[trie[p][cx]][cy],df);
        p=trie[p][cx];
    }
}
int query(int x,int y){
    //值为x,下标为y
    int ret=0,p=1;
    for(int i=_log;i>=0;--i){
        int cx=(x>>i)&1,cy=(y>>i)&1;
        if(cx)ret=max(ret,val[trie[p][0]][cy]);
        else ret=max(ret,val[trie[p][1]][!cy]);
        p=trie[p][cx];
    }
    return ret;
}
void solve(){clear();
    n=read(),ans=0;
    for(int i=0;i<n;++i){
        int x=read()^i;
        f[i]=query(x,i)+1;
        modify(x,i,f[i]);
        ans=max(ans,f[i]);
    }
    printf("%d\n",ans);
}
int main(){
    // freopen("C:\\Users\\root\\Desktop\\OI\\indata.txt","r",stdin);
    // freopen("C:\\Users\\root\\Desktop\\OI\\outdata.txt","w",stdout);
    int T=read();
    while(T--)solve();
    return 0;
}

标签:ch,运算,不等式,int,ret,trie,异或,cx
From: https://www.cnblogs.com/chenhx-xcpc/p/18499367

相关文章

  • C++运算符优先级
    在C++中,二进制运算符的优先级如下(从高到低):逻辑非(!)按位取反(~)乘法(*),除法(/),取余(%)加法(+),减法(-)左移(<<),右移(>>)关系运算符(<,<=,>,>=)等于(==),不等于(!=)按位与(&)按位异或(^)按位或(|)逻辑与(&&)逻辑或(||)条件运算符(?:)......
  • 基础运算符
    10.基础运算符一.按功能分类 二.按操作个数分类 三.算术运算符//(前)++||--先改变值后进行操作  (后)++||--先进行操作后改变值//值为布尔类型数据 四.赋值运算符 五.比较运算符//!=表示不等于  且比较运算的结果是布尔类型的数据 六.instanceof的使......
  • 数据库 NULL 值对比运算符(null safe equal)
    在SQL的规定中,NULL是不等于NULL的,所以如果使用类似SELECTNULL=NULL这种语句,获取到的会是一个FALSE。但是有些时候我们又希望能够匹配到数据库中的NULL,通常写法是SELECTNULLISNULL,但是有没有能够同时兼容NULL和非NULL的情况呢?MySQLMySQL::MySQL5.7......
  • 运算论
    运算论互换符号互换。加法化乘法:\(k_1+k_2\implies(1+k_1x)(1+k_2x)\bmodx^2\)\(\sum\frac1x=\sumln'(x)\)乘法化加法:取对数优先级考虑变换优先级:线性变换(加减乘除)>非线性可逆变换(次幂)>不可逆有结合律变换(最值:max、min、gcd、lcm)>无结合律变换(求众数、中位数)量规避......
  • 绝对值不等式
    前情概要初中所学内容,\(\sqrt{a^2}=|a|=\left\{\begin{array}{l}a,&a\geqslant0\\-a,&a<0\end{array}\right.\),是高中所学习的绝对值问题的基础。基础回顾深入理解基本类型视为其他的求解模板\(|x|\)\(\leqslant\)\(2\),则\(-2\)\(\leqslant\)\(x\leqslant\)\(2\);\(|x|\......
  • 矩阵运算
    矩阵与矩阵加减只有同型矩阵能相加减矩阵的数乘矩阵的乘法多矩阵相乘计算从右往左依次计算。如ABC,先算BC,再算A与BC的结果。矩阵相乘的前提M[mn]mulO[ij];n必须等于i;如:M5×4与O4×2能相乘。......
  • P4462 [CQOI2018]异或序列
    [CQOI2018]异或序列题目描述已知一个长度为n的整数数列\(a_1,a_2,...,a_n\),给定查询参数l、r,问在\(a_l,a_{l+1},...,a_r\)区间内,有多少子序列满足异或和等于k。也就是说,对于所有的x,y(I≤x≤y≤r),能够满足\(a_x\bigoplusa_{x+1}\bigoplus...\bigoplusa_y=k\)......
  • 蓝桥杯基本操作和运算
    文章目录1.基本运算2.循环--进制转换/最大公约数2.1进制转换2.2求解最大公约数3.数组与字符串4.常用的API5.快速读写模版蓝桥杯基本操作和运算10-22号正式开始准备蓝桥杯的比赛,准备参加这个大学B组的Java的赛项1.基本运算首先就是基本的输入输出:system.out.pr......
  • 指数不等式与对数不等式
    前情概要看到学生对指数不等式和对数不等式比较陌生,故从这篇各种不等式的解法收集博文中分离出来单独成篇,详细说明这两种恼人的不等式的解法算理.指数不等式我们知道,\(2^x\)称为指数式,那么含有指数式的不等式就可以称为指数不等式了,最简单的指数不等式,举个例子,\(2^x\)\(>\)\(......
  • 位运算笔记
    位运算笔记对二进制数进行直接操作:基础操作:例:a=00001101;b=00110101;与:a&b==00000101;//当两个数的第i位都为1时,a&b的第i位才为1或:a|b==00111101;/*当两个数的第i位都为0时,a|b的第i位才为0或者说两个数的第i位其中至少有一个为1,对应的a|b的第i位就为1*/......