CodeForces 1616H Keep XOR Low {a^b≤x} / CodeForces gym102331 Bitwise Xor {a^b≥x}(trie树 + 计数)

文章目录

  • CodeForces 1616H Keep XOR Low
    • problem
    • solution
    • code
  • CodeForces gym102331 Bitwise Xor
    • problem
    • solution
    • code

CodeForces 1616H Keep XOR Low

problem

洛谷链接

solution

虽然选的是一个子集,但本质还是二元限制。

这非常类似以前做过的题目,已知 ai,ka_i,kai,k,求满足 ai⊕aj≤ka_i\oplus a_j\le kaiajkaja_jaj 个数。

这是一元限制,常见解法是在 trie\text{trie}trie 树上统计。 紧贴 的思想。

具体而言,就像数位 dpdpdp 一样,贴着 xxx 二进制位的要求走,如果 ddd 位为 111,那么直接统计 trie\text{trie}trie 树该位 000 子树的个数,然后继续往 111 那边走。

我们考虑采用同样的方法来解决本题。只不过此时的 aia_iai 同样未知。

直接设计 dfs(x,y,d):dfs(x,y,d):dfs(x,y,d): 目前在 ddd 二进制位,从 x,yx,yx,y 子树中选取子集,仅考虑 x−yx-yxy 间限制的方案数,且前 ddd 位都是紧贴的。

首先得从高到低考虑二进制位。初始调用函数 dfs(1,1,30)dfs(1,1,30)dfs(1,1,30)。(插入以及统计子树内个数就略过了)

  • x=yx=yx=y

    • kkkddd 位为 111

      直接返回 dfs(lson[x],rson[x],d−1)dfs(lson[x],rson[x],d-1)dfs(lson[x],rson[x],d1)

    • kkkddd 位为 000

      返回 dfs(lson[x],lson[x],d−1)+dfs(rson[x],rson[y],d−1)dfs(lson[x],lson[x],d-1)+dfs(rson[x],rson[y],d-1)dfs(lson[x],lson[x],d1)+dfs(rson[x],rson[y],d1)

      这里不能乘法乱来,否则就会包含 xxx 左右儿子组合等等,这些异或在该位可是 111,超过了 kkk 限制。

  • x≠yx\ne yx=y

    • kkkddd 位为 111

      返回 dfs(lson[x],rson[y],d−1)∗dfs(rson[x],lson[y],d−1)dfs(lson[x],rson[y],d-1)*dfs(rson[x],lson[y],d-1)dfs(lson[x],rson[y],d1)dfs(rson[x],lson[y],d1)

      实际上应该是两边都要 +1+1+1 再乘,表示仅从 x,yx,yx,y 的各一个儿子中选取的方案数,直接乘就是要求 x,yx,yx,y 左右儿子中都要选择了。

      最后还要 −1-11,减去两边没一个选的空集。

      这个乘法就包含了 xxx 左右儿子组合,yyy 左右儿子组合,x,yx,yx,y 左/右儿子组合等等的可能。

      这些组合在这一位的异或都是 000,都是松弛在限制下面的。

    • kkkddd 位为 000

      返回 dfs(lson[x],lson[y],d−1)+dfs(rson[x],rson[y],d−1)dfs(lson[x],lson[y],d-1)+dfs(rson[x],rson[y],d-1)dfs(lson[x],lson[y],d1)+dfs(rson[x],rson[y],d1)

      但这里没有考虑到只选 xxx 内部的左右子树和只选 yyy 内部的左右子树的情况。

      直接加上 (2siz[lson[x]]−1)(2siz[rson[x]]−1)+(2siz[lson[y]]−1)(2siz[rson[y]]−1)(2^{siz[lson[x]]}-1)(2^{siz[rson[x]]}-1)+(2^{siz[lson[y]]}-1)(2^{siz[rson[y]]}-1)(2siz[lson[x]]1)(2siz[rson[x]]1)+(2siz[lson[y]]1)(2siz[rson[y]]1)

      为什么这里可以直接乘了,而不是继续 dfsdfsdfs 下去呢?

      注意到如果 x≠yx\neq yx=y,那么之前必定是有一个更高位使得他们分叉。

      而分叉的条件都是那个更高位上的 kkk111

      所以这里可以直接 x/yx/yx/y 子树内部各自乱选,反正异或起来至少在那个较高位都是 000

      一定是被限制松弛的方案数。

code

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define mod 998244353
#define maxn 150005
int n, m, root, cnt;
int a[maxn], mi[maxn], l[maxn * 30], r[maxn * 30], siz[maxn * 30];void insert( int &now, int d, int x ) {if( ! now ) now = ++ cnt;siz[now] ++;if( ! ~ d ) return;if( x >> d & 1 ) insert( r[now], d - 1, x );else insert( l[now], d - 1, x );
}int dfs( int x, int y, int d ) {//-1是减去空集的情况数if( ! x ) return mi[siz[y]] - 1;if( ! y ) return mi[siz[x]] - 1;if( x == y ) {if( ! ~ d ) return mi[siz[x]] - 1;else if( m >> d & 1 ) return dfs( l[x], r[x], d - 1 );else return ( dfs( l[x], l[x], d - 1 ) + dfs( r[x], r[x], d - 1 ) ) % mod;}else {if( ! ~ d ) return mi[siz[x]] * mi[siz[y]] % mod - 1;//+1乘是有可能不选这个子树中的子集else if( m >> d & 1 ) return ( dfs( l[x], r[y], d - 1 ) + 1 ) * ( dfs( r[x], l[y], d - 1 ) + 1 ) % mod - 1;else {int ans = ( dfs( l[x], l[y], d - 1 ) + dfs( r[x], r[y], d - 1 ) ) % mod;( ans += ( mi[siz[l[x]]] - 1 ) * ( mi[siz[r[x]]] - 1 ) % mod ) %= mod;( ans += ( mi[siz[l[y]]] - 1 ) * ( mi[siz[r[y]]] - 1 ) % mod ) %= mod;//这种情况计数是左右子树一定都选了的return ans;}}
}signed main() {scanf( "%lld %lld", &n, &m ); mi[0] = 1;for( int i = 1, x;i <= n;i ++ ) {scanf( "%lld", &x ), insert( root, 30, x );mi[i] = ( mi[i - 1] << 1 ) % mod;}printf( "%lld\n", ( dfs( root, root, 30 ) + mod ) % mod );return 0;
}

还有一道类似的题目,只不过限制变为了 ai⊕aj≥ka_i\oplus a_j\ge kaiajk。但做法就完全不一样了。

CodeForces gym102331 Bitwise Xor

problem

CF链接

solution

一堆数按从高到低二进制考虑,按第 www 位分为 0/10/10/1 两个集合,第 www 位产生贡献肯定是两个数隶属不同的集合。

如此递归分层下去,我们发现:从小到大排序后只用考虑相邻两个数是否满足限制。

上述结论有一个数学化的表达:a<b<c⇒min⁡(a⊕b,b⊕c)≤a⊕ca<b<c\Rightarrow \min(a\oplus b,b\oplus c)\le a\oplus ca<b<cmin(ab,bc)ac

可以大概理解为数相差越大,二进制位的高位越有可能异或为 111,异或结果越有可能更大。

因此可以将 aaa 从小到大排序,设 fi:aif_i:a_ifi:ai 结尾的序列的方案数。

转移利用 trie\text{trie}trie 树的紧贴思想去求与 aia_iai 异或 ≥x\ge xxaja_jaj 对应的方案数。

code

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define mod 998244353
#define maxn 300005
int n, m;
int a[maxn], cnt;
int trie[maxn * 65][2], sum[maxn * 65];void insert( int x, int val ) {for( int i = 60, now = 0;~ i;i -- ) {int k = x >> i & 1;if( ! trie[now][k] ) trie[now][k] = ++ cnt;now = trie[now][k];( sum[now] += val ) %= mod;}
}int query( int x ) {int ans = 0, now = 0;for( int i = 60;~ i;i -- ) {int k = x >> i & 1;if( m >> i & 1 ) now = trie[now][k ^ 1];else ( ans += sum[trie[now][k ^ 1]] ) %= mod, now = trie[now][k];if( ! now ) break; //很有可能这个数比之大的不存在 那么now就会回到0 如果继续走下去就岔了}return ( ans + sum[now] ) % mod;
}signed main() {scanf( "%lld %lld", &n, &m );for( int i = 1;i <= n;i ++ ) scanf( "%lld", &a[i] );sort( a + 1, a + n + 1 );int ans = 0; //f[i]=1+\sum_{j,a_i^a_j>=m}f[j]for( int i = 1;i <= n;i ++ ) {int val = query( a[i] ) + 1; //+1是自己单独一个的方案ans = ( ans + val ) % mod;insert( a[i], val );}printf( "%lld\n", ans );return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/316608.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET Core 文件系统

静态文件 目录浏览 默认页面 MIME类型配置 实战文件服务器 紧接上一讲 中间件 之后&#xff0c;今天来我们来讲一下关于 ASP.NET Core 中静态文件服务。什么是静态文件&#xff1f;先看一下下面例子&#xff08;在客户端浏览器中通过 url 路径访问了网站的一张图片&#xff09…

[C++] iota语句的语法

头文件为 numeric #include <numeric> using namespace std;语法和 sort / lower_bound / upper_bound 等差不多&#xff0c;都是前闭后开的原则。 iota(Ax,Ay,z) &#xff1a;表示将 AAA 数组的 [x,y)[x,y)[x,y) 区间进行填充&#xff0c;从 zzz 开始&#xff0c;每填…

如何使用vs将asp.net core项目添加容器支持并发布docker镜像到私有dockerhub和添加k8s/helm管理...

这篇文章介绍一下&#xff0c;如何使用VS2017给asp.net core添加容器支持&#xff0c;并发布镜像到私有docker hub&#xff0c;然后用chart管理容器镜像的操作流程。话不多说&#xff0c;just do it.新建项目首先新建一个asp.net core项目&#xff0c;这里我新建一个WebApi默认…

Inverse Pair

Inverse Pair 题意&#xff1a; 一个数组a&#xff0c;现在构造一个数组c&#xff0c;c[i]a[i]0/1&#xff08;0或1&#xff09;&#xff0c;使得c的逆序对最少 题解&#xff1a; 如果x在x1的后面&#xff0c;我们让x这个数1,x1不变&#xff0c;就可以让逆序对少1。如果x在…

CodeForces 1610H Squid Game(延迟贪心 + 构造 + 树状数组)

problem 洛谷链接 solution 考虑重新随便钦定一个点为“根”&#xff0c;并且强制根必须是关键点。 则所有 x−yx-yx−y 不是直系祖先-子代的要求&#xff08;要求Ⅰ&#xff09;&#xff0c;即 xxx 不是 yyy 祖先&#xff0c;yyy 也不是 xxx 祖先&#xff0c;一定都被满足…

P4551 最长异或路径

P4551 最长异或路径 题意&#xff1a; 给定一棵 n 个点的带权树&#xff0c;结点下标从 1 开始到 n。寻找树中找两个结点&#xff0c;求最长的异或路径。 异或路径指的是指两个结点之间唯一路径上的所有边权的异或。 题解&#xff1a; 我们指定1为根节点&#xff0c;T(u,v…

[小技巧]EF Core中如何获取上下文中操作过的实体

原文地址&#xff1a;https://www.cnblogs.com/lwqlun/p/10576443.html作者&#xff1a;Lamond Lu 源代码&#xff1a;https://github.com/lamondlu/EFCoreFindSample背景介绍当我们在工作单元(UnitOfWork)中使用EF/EF Core的时候&#xff0c;为了要保持事务&#xff0c;一个用…

CF1621G Weighted Increasing Subsequences(离散化+树状数组优化dp+栈维护后缀最大值+计数)

problem luogu-link solution 显然单独考虑每个 iii 的贡献&#xff0c;即被多少个合法上升子序列包含。 令 xmax⁡{j∣j>i∧aj>ai}x\max\{j\ |\ j>i\wedge a_j>a_i\}xmax{j ∣ j>i∧aj​>ai​}&#xff0c;则包含 iii 的合法子序列的结尾元素最远只能到…

Acwing 232. 守卫者的挑战

Acwing 232. 守卫者的挑战 题意&#xff1a; 有n个挑战&#xff0c;一开始背包容量为k&#xff0c;每次挑战有p[i]的概率成功&#xff0c;成功的话会得到一个大小为1的地图碎片或者是提升背包容量X&#xff0c;所有的地图碎片必须装在包里&#xff0c;问最后带地图离开的概率…

IdentityServer4-前后端分离之Vue

前言之前文章讲到如何使用Node.jsExpress构建JavaScript客户端&#xff0c;实现前后端分离。本节将介绍如何使用Vue实现前后端分离&#xff0c;文中介绍Vue的知识比较基础&#xff0c;适合新手学习。一、搭建Vue项目前提条件&#xff1a;安装nodejs、webpack和vue-cli。这个网上…

P1850 [NOIP2016 提高组] 换教室

P1850 [NOIP2016 提高组] 换教室 题意&#xff1a; 有2n个课安排在n个时间段上&#xff0c;每个时间段上都有两个一样的课同时在不同地方上&#xff0c;起初牛牛被所有课都被安排在Ci上课&#xff0c;另一节课在Di上课。牛牛现在想跟换到Di位置&#xff0c;它最多可以申请m节…

守列划分问题(圆排列+排列dp+结论)

problem 将正整数 1∼n1\sim n1∼n 任意划分成 mmm 个非空集合 A1,...,AmA_1,...,A_mA1​,...,Am​。 一个划分是守序的&#xff0c;当且仅当存在一个环排列 (p1,...,pm)(p_1,...,p_m)(p1​,...,pm​)&#xff0c;使得 max⁡Api>min⁡Api−1\max A_{p_i}>\min A_{p_{i-…

ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署(三

在上文ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署&#xff08;二&#xff09;中&#xff0c;我介绍了如何使用Azure DevOps为ASP.NET Core应用程序案例&#xff1a;tasklist搭建持续集成环境。在持续集成的过程中&#xff0c;Azure DevOps的Build Pipeline会下…

ASP.NET Core开源Web应用程序框架ABP

"作为面向服务架构(SOA)的一个变体,微服务是一种将应用程序分解成松散耦合服务的新型架构风格. 通过细粒度的服务和轻量级的协议,微服务提供了更多的模块化,使应用程序更容易理解,开发,测试,并且更容易抵抗架构侵蚀. 它使小型团队能够开发,部署和扩展各自的服务,实现开发的…

CodeForces 1517G Starry Night Camping(网络流最小割)

CodeForces 1517G Starry Night Camping problem 洛谷链接 solution 这个平行四边形的脑洞我™真的长见识了 本题最离谱的要求就是&#xff1a;平行四边形的一条边平行于 xxx 轴。 而往往这种离谱要求就是正解的途径。(((φ(◎ロ◎;)φ))) 首先不观察也能知道&#xff0c…

Acwing 307. 连通图

Acwing 307. 连通图 题意&#xff1a; 求 N 个节点的无向连通图有多少个&#xff0c;节点有标号&#xff0c;编号为 1∼N。 例如下列图示&#xff0c;三个节点的无向连通图共 4 个。 题解: 用py写 代码&#xff1a; def c(n, m):n int(n)m int(m)ret 1for i in range(…

Acwing 309. 装饰围栏

Acwing 309. 装饰围栏 题意&#xff1a; 有n个模板&#xff0c;长度分别是1到N&#xff0c;现在按照高低交错的方式排列模板&#xff0c;能到的很多种排列的方案。 每个方案都可以写作一个长度为N的序列&#xff0c;序列中的个元素是木板的长度&#xff0c;把这些序列按照字典…

CodeForces 901D Weighting a Tree(结论)

problem 洛谷链接 注意&#xff1a;保证 C[v]C[v]C[v] 的奇偶性与顶点 vvv 的度的奇偶性相同。 solution 先考虑树的情况。这是个经典问题了&#xff0c;从叶子往上推&#xff0c;对于一个点还差的边权就有这个点和其父亲的边来补足。最后判断根是否满足条件即可。 那么怎…

CF938E Max History

CF938E Max History 题意&#xff1a; 我们定义f(a)为&#xff1a; 1、开始时&#xff0c;f(a)0,M1。 2、对于每个2<i<n,如果a[M]<a[i],那么f(a)f(a)a[M],Mi。 现在对于一个给定的数组a&#xff0c;求其所有排列的f(a)之和&#xff0c;答案对1e97取模。 题解&am…

最大限度地降低多线程 C# 代码的复杂性

分支或多线程编程是编程时最难最对的事情之一。这是由于它们的并行性质所致&#xff0c;即要求采用与使用单线程的线性编程完全不同的思维模式。对于这个问题&#xff0c;恰当类比就是抛接杂耍表演者&#xff0c;必须在空中抛接多个球&#xff0c;而不要让它们相互干扰。这是一…