ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

AtCoder Regular Contest 141 - B - Increasing Prefix XOR

2022-05-30 18:36:11  阅读:251  来源: 互联网

标签:digits AtCoder XOR log 141 int 60 位数 oplus


原文

Consider the problem in binary.

If positive integers \(a\) and \(b\) have the same number of digits, the only case when both \(a<c\) and \(b < b\oplus c\) hold is when \(c\) has more digits than each of \(a\) and \(b\), in which case \(c\) and \(b \oplus c\) have the same number of digits.

From this, it can be inductively shown that when \(A\) satisfies the conditions, \(A_{i+1}\) has more digits than \(A_i\). On the other hand, if \(A_{i+1}\) has more digits than \(A_i\) for every \(i\), the conditions are obviously satisfied.

Therefore, when \(M < 2^{60}\), the answer is \(0\) if \(60 < N\). Otherwise, let us precompute the number of \(k\)-digit integers between \(1\) and \(M\) to solve the problem in \(O(N\log^2 M)\) time by dynamic programming, where we set

\(dp[n][k]:\) the number of sequences \((A_1,\ A_2,\ \dots,\ A_n)\) of positive integers with increasing numbers of digits whose \(A_n\) has \(k\) digits.

(Alternatively, consider taking at most one \(k\)-digit integer for each \(k\) to choose \(N\) in total, to solve it in \(O(N \log M)\) time.)

Therefore, the problem can be solved in \(O(\log^3{M})\) or \(O(\log^2 {M})\) time.

解释:

我们从二进制的角度来解决这个问题。

如果两个正整数a,b在二进制下有相同的位数,若希望\(a<c\) 和 \(b < b\oplus c\) 均成立,只有\(c\)的位数比\(a,b\)都多才能满足。在这种情况下,\(c\) 和 \(b \oplus c\) 的位数是相同的。

换句话说,若\(a<c\) 和 \(b < b\oplus c\) 均成立,则必有\(c\)的位数比\(a,b\)都多(注意前提条件,a,b的位数相同)。

为什么呢?

从右式出发,显然c的位数不可能小于b,假设c的位数和b相同,均为\(n\)。

显然它们的最高位必然均为1,则异或的结果的位数必然小于\(n\),故\(b > b \oplus c\),与原条件矛盾,故假设不成立。

故\(c\)的位数大于\(a,b\)的位数

由此,当序列\(A\)满足条件时,有\(A_{i+1}\)的位数多于\(A_i\)。另一方面,如果\(A_{i+1}\)的位数均大于\(A_i\),则显然能满足条件。

这里相当于令上文的\(a = A_i, b = B_i, c = A_{i + 1}\)

需要补充说明:

  • 原条件:\(B_1<B_2<⋯<B_N, \text {where } B_i = A_1 \oplus A_2 \oplus \dots \oplus A_i.\)
  • \(B_i的位数 = A_i的位数,即b = a\) 的必要条件是\(A_{i+1}\)的位数均大于\(A_i\)
  • \(B_{i + 1}= B_i \oplus A_{i+ 1}\)
  • \(A_i = B_i\oplus A_1 \oplus A_2 \oplus ...\oplus A_{i - 1}\)

因此,当\(M<2^{60}\)时,如果\(N > 60\),答案就是\(0\)。

\(A_i\)的位数是单调递增的,若\(N > 60\),则必存在\(A_i,A_i\)的位数\(>60\),而条件限制\(A_i\le M\),显然有矛盾,故答案为0

否则,让我们预先计算\(1\)到\(M\)之间的长度为\(k\)(二进制下)的整数的个数,通过动态规划在\(O(Nlog^2 M)\)的时间内解决这个问题,其中我们设定

\(dp[n][k]:\)由位数单调递增的正整数组成的,长度为n的序列\((A_1,\ A_2,\ \dots,\ A_n)\)构成的集合的元素个数,且其中\(A_n\)有\(k\)位数。

\(dp(n, k) = cnt[k]* \sum_{j=1}^{k-1}dp(i-1, j)\),其中cnt[k]为位数为k的整数的数量

(或者,考虑在每一个\(k\)中最多取一个\(k\)位数的整数,总共选择\(N\)次,以\(O(N\log M)\)的时间来解决。)

Alternatively, consider taking at most one \(k\)-digit integer for each \(k\) to choose \(N\) in total, to solve it in \(O(N \log M)\) time.

这里实在看不太明白==

因此,这个问题可以在\(O(\log^3{M})\)或\(O(\log^2 {M})\)时间内解决。

代码

// Problem: B - Increasing Prefix XOR
// Contest: AtCoder - AtCoder Regular Contest 141
// URL: https://atcoder.jp/contests/arc141/tasks/arc141_b
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 61, mod = 998244353;
typedef long long LL;

LL n, m, ans;
int f[N][N];
LL cnt[N];

int main(void){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	
	cin >> n >> m;
	
	int size = 0;
	LL t = m;
	while (t){
		size ++ ;
		t >>= 1;
	}
	
	for (int i = 1; i <= 60; i ++ ){		// cnt[i]表示位数为 i 的,不超过 m 的整数的个数
		if (i < size)	cnt[i] = 1ll << (i - 1);
		if (i == size)	cnt[i] = m + 1 - (1ll << (i - 1));
		if (i > size) break;
		f[1][i] = cnt[i];
	}

	if (n > 60){
		cout << "0" << endl;
		return 0;
	}
	
	for (int i = 2; i <= n; i ++ ){			// 长度
		for (int j = 1; j <= size; j ++ ){	// A_n的位数
			for (int k = 1; k < j; k ++ ){	// A_(n-1)的位数
				f[i][j] = (f[i][j] + f[i - 1][k]) % mod;
			}
			f[i][j] = cnt[j] % mod * f[i][j] % mod;
		}
	}
	for (int i = 0; i <= 60; i ++ ) ans = (ans + f[n][i]) % mod;
	cout << ans << endl;
	
    return 0;
}

疑惑

我想用前缀和优化一维,但是改来改去还是wa:(

失败1

失败2

标签:digits,AtCoder,XOR,log,141,int,60,位数,oplus
来源: https://www.cnblogs.com/tsrigo/p/16327753.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有