当前位置: 首页 > news >正文

2025牛客多校第八场 根号-2进制 个人题解

J.根号-2进制

#数学 #FFT
image

思路

赛后发现身边的同学都是通过借位来解决进位问题的,在此提供一种全程不出现减法的顺推做法

首先A,BA,BA,B可以理解为两个多项式:A0+A1−2+A2(−2)2+…A_{0}+A_{1}\sqrt{ -2 }+A_{2}(\sqrt{ -2 })^2+\dotsA0+A12+A2(2)2+,其中Ai={0,1}A_{i}=\{ 0,1 \}Ai={0,1}BiB_{i}Bi同理

那么可以使用多项式乘法FFTFFTFFT先将A,BA,BA,B相乘后的结果表示为一个新的多项式CCC,此时该多项式的系数CiC_{i}Ci不一定为{0,1}\{ 0,1 \}{0,1}

因此我们的任务变为了如何将一个多项式的系数在−2\sqrt{ -2 }2进制下全部化为{0,1}\{ 0,1 \}{0,1}

为了方便观察,将−2\sqrt{ -2 }2写为212i2^{\frac{1}{2}}i221i,则(−2)k=2k2ik(\sqrt{ -2 })^k=2^{\frac{k}{2}}i^k(2)k=22kik

打表观察:
i=1:212ii=2:−222i=3:−232ii=4:242i=5:252ii=6:−262\begin{align} &i=1:\quad 2^{\frac{1}{2}}i\\ \\ &i=2:\quad -2^{\frac{2}{2}}\\ \\ &i=3:\quad -2^{\frac{3}{2}}i \\ \\ &i=4:\quad 2^{\frac{4}{2}}\\ \\ &i=5:\quad 2^{\frac{5}{2}}i\\ \\ &i=6:\quad -2^{\frac{6}{2}} \end{align} i=1:221ii=2:222i=3:223ii=4:224i=5:225ii=6:226
发现明显规律且周期T=4T=4T=4

a=−2a=\sqrt{ -2 }a=2,则必有22×ap=ap+42^2\times a^p=a^{p+4}22×ap=ap+4
进一步推广:
22k×ap=ap+4k2^{2k}\times a^p=a^{p+4k} 22k×ap=ap+4k
现在解决了222的偶数次幂与aaa的任意次幂相乘的递推,如果能够解决222的奇数次幂与aaa任意次幂相乘的递推,那么就可以通过对多项式系数CiC_{i}Ci二进制分解不断递推,将所有系数化为{0,1}\{ 0,1 \}{0,1}

由于22k+1=22k×22^{2k+1}=2^{2k}\times 222k+1=22k×2,因此解决2×ap2\times a^p2×ap的递推即可

观察表格可知2×ap=−ap+22\times a^p=-a^{p+2}2×ap=ap+2,即2×ap+ap+2=02\times a^p+a^{p+2}=02×ap+ap+2=0
因此有2×ap+ap+2=2×ap+2+ap+4=02\times a^p+a^{p+2}=2\times a^{p+2}+a^{p+4}=02×ap+ap+2=2×ap+2+ap+4=0
则有:
2×ap=ap+2+ap+42\times a^p=a^{p+2}+a^{p+4} 2×ap=ap+2+ap+4
这样就能不断地将系数向高次推推推,最终全部推成{0,1}\{ 0,1 \}{0,1}啦!

然而,聪明的phaethon90phaethon 90phaethon90发现了问题:
如果原本的多项式在推导过程中包含形如2×ap+ap+2+…2\times a^p+a^{p+2}+\dots2×ap+ap+2+的部分,那么对2×ap2\times a^p2×ap套用上述递推将导致无限循环,因为2×ap+ap+2=02\times a^p+a^{p+2}=02×ap+ap+2=0

因此,在使用第二个递推前,先判断ap+2a^{p+2}ap+2项的系数是否为奇数:

  • 如果为奇数,那么就可以利用2×ap+ap+2=02\times a^p+a^{p+2}=02×ap+ap+2=0将这个奇数消去,避免在处理到p+2p+2p+2位时仍然是个奇数
  • 如果为偶数,那么可以利用递推二2×ap=ap+2+ap+42\times a^p=a^{p+2}+a^{p+4}2×ap=ap+2+ap+4往高位推

当更新过的最高位已经与当前位重合了,那么就退出循环

fun fact:这个代码在赛事实际上早就写好了,但是因为不知道如何给FFT清空,以及没有发现最后输出的多项式的项数size远大于size(A)+size(B),导致没有清空完全,一直在WAAAAA

代码实现

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
#include<cmath>
#include<unordered_map>
#include<numeric>
using namespace std;
using ll = long long;
#define rep(i, a, b) for(ll i = (a); i <= (b); i ++)
#define per(i, a, b) for(ll i = (a); i >= (b); i --)
#define see(stl) for(auto&ele:stl)cout<<ele<<" "; cout<<'\n';
constexpr ll inf = 1e9 + 5;
#define int ll
#define double long double
constexpr ll  mod = 998244353;const double pi = acos(-1);const int N = 4e5 + 5;struct complex {double x, y;complex operator+(const complex& t)const {return{ x + t.x,y + t.y };}complex operator-(const complex& t)const {return{ x - t.x,y - t.y };}complex operator*(const complex& t)const {return{ x * t.x - y * t.y,x * t.y + y * t.x };}
}A[N], B[N];
int R[N];void FFT(complex A[], int n, int op) {rep(i, 0, n - 1)R[i] = R[i / 2] / 2 + ((i & 1) ? n / 2 : 0);rep(i, 0, n - 1)if (i < R[i])swap(A[i], A[R[i]]);for (int i = 2; i <= n; i <<= 1) {complex w1({ cos(2 * pi / i),sin(2 * pi / i) * op });for (int j = 0; j < n; j += i) {complex wk({ 1,0 });rep(k, j, j + i / 2 - 1) {complex x = A[k], y = A[k + i / 2] * wk;A[k] = x + y; A[k + i / 2] = x - y;wk = wk * w1;}}}
}
int n = 0, m = 0,pos=0;
int ans[N+10];
void eachT() {string s1, s2; cin >> s1 >> s2;int up=max(n,m);up=max(up,pos);rep(i, 0, up+5) {A[i] = B[i] = { 0,0 };R[i] =ans[i]=0;}n = s1.length() - 1, m = s2.length() - 1;rep(i, 0, n)A[i].x = s1[n - i] - '0', A[i].y = 0;rep(i, 0, m)B[i].x = s2[m - i] - '0', B[i].y = 0;for (m = n + m, n = 1; n <= m; n <<= 1);FFT(A, n, 1); FFT(B, n, 1);rep(i, 0, n - 1)A[i] = A[i] * B[i];FFT(A, n, -1);int highid = 0;bool all0 = 1;rep(i, 0, m) {ans[i] = (int)(A[i].x / n + 0.5);if (ans[i] != 0)all0 = 0;if (ans[i] > 0 && i > highid) {highid = i;}}if (all0) {cout << 0 << '\n';return;}pos = 0;while (1) {int k = ans[pos], cnt = 0;ans[pos] = (k & 1);k >>= 1;while (k) {cnt++;//2^cntif (k & 1) {if (cnt % 2 == 0) {//2^2kans[pos + 4 * cnt / 2];ans[pos + 4 * cnt / 2]++;highid=max(highid,pos + 4 * cnt / 2);}else {if (cnt / 2 == 0) {//2^1if (ans[pos + 2] % 2 == 0) {ans[pos + 4];ans[pos + 4] += 1;ans[pos + 2] += 1;highid=max(highid,pos + 4);}else {ans[pos + 2] -= 1;highid=max(highid,pos + 2);}}else {//2^2k+1ans[pos + cnt / 2 * 4];ans[pos + cnt / 2 * 4] += 2;highid=max(highid,pos + cnt / 2 * 4);}}}k >>= 1;}if (pos == highid)break;pos++;}int st = pos;per(i, pos, 0){if (ans[i] != 0){st = i;break;}}if(st==pos&&ans[pos]==0){cout<<0<<'\n';return;}per(i, st, 0)cout << ans[i];cout << '\n';
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);ll t = 1;cin >> t;while (t--) {eachT();}
}
http://www.dtcms.com/a/326625.html

相关文章:

  • HTTPS应用层协议-CA签名与证书
  • Vue 3 快速入门 第六章
  • MaixPy简介
  • Projects
  • 进程管理是什么
  • DeepSeek生成的高精度大数计算器
  • 自制网页并爬取,处理异常值(第十九节课内容总结)
  • .NET/C# webapi框架下给swagger的api文档中显示注释(可下载源码)
  • MP3Tag 软件功能简介
  • (二)vscode搭建espidf环境,配置wsl2
  • 第16届蓝桥杯Python青少组中/高级组选拔赛(STEMA)2025年4月真题
  • 进阶版|企业级 AI Agent 的构建实践
  • 【03】厦门立林科技——立林科技 嵌入式 校招笔试,题目记录及解析
  • 从零开始的ReAct Agent尝试
  • 应用监控工具Skywalking
  • bitbake –s:列出所有可编译的模块
  • 【STL】queue队列容器
  • priority_queue(优先级队列)和仿函数
  • ArkUI中的自定义组件(一)
  • 用于计算的程序是部署在哪里,为什么可以这样?
  • 从 WebView2 迁移至 DotNetBrowser:第一部分
  • android 换肤框架详解2-LayoutInflater源码解析
  • 《零基础入门AI:深度学习基础核心概念解析(从激活函数到反向传播)》
  • 大模型提示词工程实践:提示词工程实践-引导大模型完成任务
  • 直播美颜SDK架构设计指南:美白滤镜的高效实现与跨平台适配
  • MySQL 基本语法
  • 【网络基础】深入理解 TCP/IP 协议体系
  • 秒懂边缘云|1分钟了解边缘安全加速 ESA
  • GCC C++实现Matlab矩阵计算和数学函数功能
  • 乡土诗性的多重奏鸣——儿歌《生我养我的小村庄》文学赏析