Solution -「Gym 102956A」Belarusian State University
\(\mathcal{Description}\)
Link.
给定两个不超过 \(2^n-1\) 次的多项式 \(A,B\),对于第 \(i\in[0,n)\) 个二进制位,定义任意一个二元加法 \(\oplus_i:\{0,1\}\times\{0,1\}\rightarrow\{0,1\}\),而对于两个整数 \(u,v\in[0,2^n)\),定义 \(u\oplus v=\sum_{i=0}^{n-1}(u_i\oplus_i v_i)2^i\)。求 \(A,B\) 的 \(\oplus\) 卷积,保证答案任意系数不超过 \(2^{63}-1\)。
\(\mathcal{Solution}\)
可以看出这个问题不弱于 FWT,所以我们大概需要根据 FWT 的思路,来 DIY 一个变换。
在 FWT 的框架下,枚举每个二进制位,对 \(16\) 种不同的加法分别构造各自的变换方式,构造时只需要考虑 \((a_0+a_1x)\) 与 \((b_0+b_1x)\) 的卷积,使得这个卷积合法即可。
复杂度 \(\mathcal O(2^nn)\)。
\(\mathcal{Code}\)
不要用 switch!不要用 switch!不要用 switch!这个语法真的离谱。
啊……极少地在代码里爆了粗口,以记录我分类讨论加上被 switch 弄傻的愉悦!(
/*~Rainybunny~*/
#include <cstdio>
#include <cassert>
#define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
#define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i )
typedef long long LL;
const int MAXN = 18, MAXL = 1 << MAXN;
int n;
LL a[MAXL + 5], b[MAXL + 5];
char op[MAXN + 5][4];
inline int type( const char* o ) {
int ret = 0;
per ( i, 3, 0 ) ret = ret << 1 | ( o[i] ^ '0' );
return ret;
}
inline void fuckin_wa_tle( const int len, LL* u, const int tp ) {
// { -1: first item, 0: result, 1: second item }.
#define swp( a, b ) void( a ^= b ^= a ^= b )
for ( int i = 0, stp = 1; stp < len; ++i, stp <<= 1 ) {
for ( int j = 0; j < len; j += stp << 1 ) {
rep ( k, j, j + stp - 1 ) {
LL &p = u[k], &q = u[k + stp];
switch ( type( op[i] ) ) {
// what fuckin stupid grammar??? I'll never `switch` again.
case 0:
if ( !~tp ) p += q, q = 0;
else if ( tp ) p += q, q = 0;
break;
case 1:
if ( !~tp ) swp( p, q ), p += q;
else if ( tp ) swp( p, q ), p += q;
else p -= q;
break;
case 2:
if ( !~tp ) swp( p, q ), p += q;
else if ( tp ) p += q;
else p -= q;
break;
case 3:
if ( !~tp ) swp( p, q );
else if ( tp ) p = q = p + q;
break;
case 4:
if ( !~tp ) p += q;
else if ( tp ) swp( p, q ), p += q;
else p -= q;
break;
case 5:
if ( !~tp ) p = q = p + q;
else if ( tp == 1 ) swp( p, q );
break;
case 6:
p += q, q = p - 2 * q;
if ( !tp ) {
assert( !( p % 2 ) && !( q % 2 ) );
p /= 2, q /= 2;
}
break;
case 7:
if ( !~tp ) swp( p, q ), q += p;
else if ( tp ) swp( p, q ), q += p;
else q -= p;
break;
case 8:
if ( !~tp ) p += q;
else if ( tp ) p += q;
else p -= q;
break;
case 9:
q += p, p = q - 2 * p;
if ( !tp ) {
assert( !( p % 2 ) && !( q % 2 ) );
p /= 2, q /= 2;
}
break;
case 10:
if ( !~tp ) p = q = p + q;
break;
case 11:
if ( !~tp ) swp( p, q ), q += p;
else if ( tp ) q += p;
else q -= p;
break;
case 12:
if ( tp == 1 ) p = q = p + q;
break;
case 13:
if ( !~tp ) q += p;
else if ( tp ) swp( p, q ), q += p;
else q -= p;
break;
case 14:
if ( !~tp ) q += p;
else if ( tp ) q += p;
else q -= p;
break;
case 15:
if ( !~tp ) q += p, p = 0;
else if ( tp ) q += p, p = 0;
break;
default: assert( false );
}
}
}
}
#undef swp
}
int main() {
scanf( "%d", &n );
rep ( i, 0, n - 1 ) scanf( "%s", op[i] );
rep ( i, 0, ( 1 << n ) - 1 ) scanf( "%lld", &a[i] );
rep ( i, 0, ( 1 << n ) - 1 ) scanf( "%lld", &b[i] );
fuckin_wa_tle( 1 << n, a, -1 ), fuckin_wa_tle( 1 << n, b, 1 );
rep ( i, 0, ( 1 << n ) - 1 ) a[i] *= b[i];
fuckin_wa_tle( 1 << n, a, 0 );
rep ( i, 0, ( 1 << n ) - 1 ) {
printf( "%lld%c", a[i], i < repi ? ' ' : '\n' );
}
return 0;
}
Solution -「Gym 102956A」Belarusian State University的更多相关文章
- Solution -「Gym 102979E」Expected Distance
\(\mathcal{Description}\) Link. 用给定的 \(\{a_{n-1}\},\{c_n\}\) 生成一棵含有 \(n\) 个点的树,其中 \(u\) 连向 \([1, ...
- Solution -「Gym 102979L」 Lights On The Road
\(\mathcal{Description}\) Link. 给定序列 \(\{w_n\}\),选择 \(i\) 位置的代价为 \(w_i\),要求每个位置要不被选择,要不左右两个位置至少被 ...
- Solution -「Gym 102956F」Find the XOR
\(\mathcal{Description}\) Link. 给定 \(n\) 个点 \(m\) 条边的连通无向图 \(G\),边有边权.其中 \(u,v\) 的距离 \(d(u,v)\) ...
- Solution -「Gym 102956B」Beautiful Sequence Unraveling
\(\mathcal{Description}\) Link. 求长度为 \(n\),值域为 \([1,m]\) 的整数序列 \(\lang a_n\rang\) 的个数,满足 \(\not\ ...
- Solution -「Gym 102956F」Border Similarity Undertaking
\(\mathcal{Description}\) Link. 给定一张 \(n\times m\) 的表格,每个格子上写有一个小写字母.求其中长宽至少为 \(2\),且边界格子上字母相同的矩 ...
- Solution -「Gym 102798I」Sean the Cuber
\(\mathcal{Description}\) Link. 给定两个可还原的二阶魔方,求从其中一个状态拧到另一个状态的最小步数. 数据组数 \(T\le2.5\times10^5\). ...
- Solution -「Gym 102798K」Tree Tweaking
\(\mathcal{Description}\) Link. 给定排列 \(\{p_n\}\),求任意重排 \(p_{l..r}\) 的元素后,将 \(\{p_n\}\) 依次插入二叉搜索树 ...
- Solution -「Gym 102798E」So Many Possibilities...
\(\mathcal{Description}\) Link. 给定非负整数序列 \(\{a_n\}\) 和 \(m\),每次随机在 \(\{a\}\) 中取一个非零的 \(a_i\)(保证存 ...
- Solution -「Gym 102759I」Query On A Tree 17
\(\mathcal{Description}\) Link. 给定一棵含 \(n\) 个结点的树,结点 \(1\) 为根,点 \(u\) 初始有点权 \(a_u=0\),维护 \(q\) 次 ...
随机推荐
- 【Spring专场】「AOP容器」不看源码就带你认识核心流程以及运作原理
前提回顾 前一篇文章主要介绍了spring核心特性机制的IOC容器机制和核心运作原理,接下来我们去介绍另外一个较为核心的功能,那就是AOP容器机制,主要负责承接前一篇代理模式机制中动态代理:JDKPr ...
- 使用 MVVM Toolkit Source Generators
关于 MVVM Toolkit 最近 .NET Community Toolkit 发布了 8.0.0 preview1,它包含了从 Windows Community Toolkit 迁移过来的以下 ...
- 学习JAVAWEB第三天
## 数据库的设计· 1. 多表之间的关系 1. 分类: 1. 一对一(了解): * 如:人和身份证 * 分析:一个人只有一个身份证,一个身份证只能对应一个人 2. 一对多(多对一): * 如:部门和 ...
- linux 启动过程原理哦
bios加电自检硬件设备 grub引导加载程序 当内核被加载到内存,内核阶段就开始了. init进程是所有进程的发起者和控制者.因为在任何基于unix的系统中,它都是第一个运行的进程. 然后执行sys ...
- Java高并发下多线程编程
1.创建线程 Java中创建线程主要有三种方式: 继承Thread类创建线程类: 定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务.因此也把run方法称为 ...
- 如何在pyqt中使用 QGraphicsView 实现图片查看器
前言 在 PyQt 中可以使用很多方式实现照片查看器,最朴素的做法就是重写 QWidget 的 paintEvent().mouseMoveEvent 等事件,但是如果要在图像上多添加一些形状,那么在 ...
- Spring源码-AOP部分-Spring是如何对bean实现AOP代理的
实验环境:spring-framework-5.0.2.jdk8.gradle4.3.1 历史文章 Spring源码-IOC部分-容器简介[1] Spring源码-IOC部分-容器初始化过程[2] S ...
- 我在 Gitee 上发现了一个简洁又好用的网络音乐播放器!
这几天无聊的时候我想听听歌,但我想要找一个简单快速的网络音乐播放器来用用.这时我在 Gitee 上看见一个看上去不错的开源项目 -- Hi音乐. 项目链接:https://gitee.com/hi-j ...
- 如何为Windows服务增加Log4net和EventLog的日志功能。
一.简介 最近在做一个项目的时候,需要该项目自动启动.自动运行,不需要认为干预.不用说,大家都知道用什么技术,那就是 Windows服务.在以前的Net Framework 平台下,Windows 服 ...
- AI 智能写情诗、藏头诗
一.AI 智能情诗.藏头诗展示 最近使用PyTorch的LSTM训练一个写情诗(七言)的模型,可以随机生成情诗.也可以生成藏头情诗. 在特殊的日子用AI生成一首这样的诗,是不是很酷!下面分享下AI 智 ...