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\) 次 ...
随机推荐
- Linux下校验SHA1和MD5的方法
当我们从互联网下载东西或者从U盘拷贝东西的时候,通常是不会和源文件有什么区别的,但是在偶然的情况下会出现下载或者拷贝出错的情况, 尤其是在下载大文件的时候,比如系统光盘......当你装机到一半才发现 ...
- Jupyter常用配置
一 安装 pip install --upgrade jupyterthemes 二 设置主题 #查看主题列表 jt -l #设置主题并打开工具栏 jt -t chesterish -T 三 设置列 ...
- List接口的实现类
(一): ArrayList 构造方法 特有的方法: LinkedList 特点: 可以调用Collections类的静态方法 synchronizedCollection转换成线程安全的
- Rust学习(一)
为什么学习Rust 最近在看Linux相关新闻的时候,看到了Linux内核正在将Rust集成至内核内的消息,且越来越多的嵌入式开发可以使用Rust编程.以往笔者的技术栈只有 C语言 ,C++也只是浅尝 ...
- Genymotion模拟器配置与使用
1.https://www.genymotion.com网站注册模拟器账号,并按照指引激活账号 此过程中提示商业用还是个人使用,商业使用需要有注册码,个人使用不需要注册码,我选择的是个人使用. 2.激 ...
- Android Sensor.TYPE_STEP_COUNTER 计步器传感器 步数统计
注意:使用 计步器传感器 Sensor.TYPE_STEP_COUNTER 获取步数前需要手机支持该传感器 1.学习资料 1.1 SENSOR.TYPE_STEP_COUNTER 地址:开发者文档 翻 ...
- 【Android】安卓开发中的布局与事件
[Android]安卓开发中的布局与事件 1.Android Studio下载配置 非常简单的百度然后点击下载安装就好了.注意的是,本来我是打算使用评价还不错的Genymotion这个软件来充当虚拟机 ...
- php的CI框架相关数据库操作
在使用之前首先应该配置数据库的参数,详见文件application/config/database.php,里面包含主机名,登陆用户名,登录密码,数据库名,编码信息等. 在配置成功后,可以简单的调用: ...
- QT之鼠标事件
Widget.h: #ifndef WIDGET_H #define WIDGET_H #include<QWidget> #include<QMouseEvent> clas ...
- 不难懂------适配移动端flexible
基于 vue-cli 配置手淘的 lib-flexible + rem,实现移动端自适应 安装 flexible npm install lib-flexible --save 引入 flexible ...