当前位置: 首页 > 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.lryc.cn/news/617796.html

相关文章:

  • USB 基本描述符
  • TRL - Transformer Reinforcement Learning SFTTrainer 和 SFTConfig
  • AI(2)-神经网络(激活函数)
  • 当生产环境卡成 PPT:Spring Boot 线程 Dump 捉妖指南 - 第544篇
  • 【09-神经网络介绍2】
  • 数据结构-排序(2)
  • 【排序算法】⑦归并排序
  • 用Python从零开始实现神经网络
  • 【08-神经网络介绍】
  • STM32 HAL库 HAL_TIM_OC_Start函数解读
  • maven项目打包成sdk后在别的项目使用
  • 深度解析三大HTTP客户端(Fetch API、Axios 和 Alova)——优劣与选择策略
  • 【03】厦门立林科技——立林科技 嵌入式 校招笔试,题目记录及解析
  • REDIS 各种数据结构有什么作用?都能干什么?
  • 写一篇Ping32和IP-Guard的对比,重点突出Ping32
  • 使用行为树控制机器人(一) —— 节点
  • 芯片学习 8 :IP集成、cluster、lint
  • 大语言模型(LLM)核心概念与应用技术全解析:从Prompt设计到向量检索
  • AI入门学习--如何写好prompt?
  • MySQL 数据操作全流程:创建、读取、更新与删除实战
  • 高精度蓝牙定位:技术、应用与未来发展
  • 【Docker实战进阶】Docker 实战命令大全
  • 从零构建企业级K8S:高可用集群部署指南
  • LeetCode算法日记 - Day 8: 串联所有单词的子串、最小覆盖子串
  • kubeadm搭建生产环境的双master节点k8s高可用集群
  • Android视频编辑方案测评:轻量化剪辑工具的性能表现
  • LAZADA跨境电商自养号测评环境搭建:安全与合规的底层逻辑解析
  • Centos8系统在安装Git包时,报错:“没有任何匹配: git”
  • 【图像处理基石】UE输出渲染视频,有哪些画质相关的维度和标准可以参考?
  • LVPECL、LVDS、LVTTL、LVCMOS四种逻辑电平标准的全面对比