# BZOJ5300 [CQOI2018]九连环 题解 | 高精度 FFT
今天做了传说中的CQOI六道板子题……有了一种自己很巨的错觉(雾
题面
求n连环的最少步数,n <= 1e5。
题解
首先……我不会玩九连环……
通过找规律(其实是百度搜索)可知,\(n\)连环的最少步数是\(\lfloor\frac{2^{n + 1}}{3}\rfloor\)。
(实际上,九连环的步骤恰好是一个叫【格雷码】的编码方式中的\(1\)一直到\(2^{n+1}-1\)!)
然后我们要输出这个\(\lfloor\frac{2^{n + 1}}{3}\rfloor\)就好了。
然后我们发现——毒瘤出题人让我们写高精度。
……那就只能写咯……
用FFT做高精度乘法,封装起来,然后正常进行快速幂即可。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#define enter putchar('\n')
#define space putchar(' ')
using namespace std;
typedef long long ll;
template <class T>
void read(T &x){
char c;
bool op = 0;
while(c = getchar(), c < '0' || c > '9')
if(c == '-') op = 1;
x = c - '0';
while(c = getchar(), c >= '0' && c <= '9')
x = x * 10 + c - '0';
if(op == 1) x = -x;
}
template <class T>
void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar('0' + x % 10);
}
const int N = 150000;
const double PI = acos(-1);
int T, x;
struct cp {
double a, b;
cp(){}
cp(double x, double y): a(x), b(y){}
cp operator + (const cp &obj) const {
return cp(a + obj.a, b + obj.b);
}
cp operator - (const cp &obj) const {
return cp(a - obj.a, b - obj.b);
}
cp operator * (const cp &obj) const {
return cp(a * obj.a - b * obj.b, a * obj.b + b * obj.a);
}
} inv[N], omg[N];
void init(int n){
for(int i = 0; i < n; i++){
omg[i] = cp(cos(2 * PI / n * i), sin(2 * PI / n * i));
inv[i] = cp(omg[i].a, -omg[i].b);
}
}
void fft(cp *a, int n, cp *omg){
int lim = 0;
while((1 << lim) < n) lim++;
for(int i = 0; i < n; i++){
int t = 0;
for(int j = 0; j < lim; j++)
if(i >> j & 1) t |= 1 << (lim - j - 1);
if(i < t) swap(a[i], a[t]);
}
for(int l = 2; l <= n; l <<= 1){
int m = l / 2;
for(cp *p = a; p != a + n; p += l)
for(int i = 0; i < m; i++){
cp t = omg[n / l * i] * p[i + m];
p[i + m] = p[i] - t;
p[i] = p[i] + t;
}
}
}
struct big {
int g[N], len;
big(){
memset(g, 0, sizeof(g));
len = 1;
}
big(int x){
memset(g, 0, sizeof(g));
len = 0;
if(!x){
len = 1;
return;
}
while(x) g[len++] = x % 10, x /= 10;
}
void out(){
for(int i = len - 1; i >= 0; i--)
printf("%d", g[i]);
enter;
}
void operator /= (int x){
int sum = 0, newlen = 0;
for(int i = len - 1; i >= 0; i--){
sum = sum * 10 + g[i];
if(sum < x) g[i] = 0;
else{
if(!newlen) newlen = i + 1;
g[i] = sum / x;
sum %= x;
}
}
len = max(newlen, 1);
}
void operator *= (const big &b){
static cp A[N], B[N];
int newlen = len + b.len - 1, n = 1;
while(n < newlen) n <<= 1;
for(int i = 0; i < n; i++){
A[i] = cp(i < len ? g[i] : 0, 0);
B[i] = cp(i < b.len ? b.g[i] : 0, 0);
}
init(n);
fft(A, n, omg);
fft(B, n, omg);
for(int i = 0; i < n; i++)
A[i] = A[i] * B[i];
fft(A, n, inv);
for(int i = 0; i < newlen; i++)
g[i] = (int)floor(A[i].a / n + 0.5);
g[len = newlen] = 0;
for(int i = 0; i < len; i++)
g[i + 1] += g[i] / 10, g[i] %= 10;
if(g[len]) len++;
}
} ret, a;
int main(){
read(T);
while(T--){
read(x), x++;
ret = big(1), a = big(2);
while(x){
if(x & 1) ret *= a;
a *= a;
x >>= 1;
}
ret /= 3;
ret.out();
}
return 0;
}
# BZOJ5300 [CQOI2018]九连环 题解 | 高精度 FFT的更多相关文章
- 【BZOJ5300】[CQOI2018]九连环 (高精度,FFT)
[BZOJ5300][CQOI2018]九连环 (高精度,FFT) 题面 BZOJ 洛谷 题解 去这里看吧,多么好 #include<iostream> #include<cstdi ...
- BZOJ5300:[CQOI2018]九连环——题解
一种打表的方法,适用于知道如何解九连环的人. 我们知道,解九(n)连环必须先解第九(n)环,然后解八(n-1).七(n-2)-- 根据这个我们飞快的写出了一个递推式,设\(f[i]\)为\(i\)连环 ...
- BZOJ5300 [Cqoi2018]九连环 【数学】【FFT】
题目分析: 这道题是数学必修五的原题,做法如下图,书上讲得很详细了. 那么这道题目用快速幂就可以解决了,值得注意的是,分析时间复杂度会发现直接做乘法其实是O(n^2)的,但是有一个1/20左右的常数, ...
- 2019.01.02 bzoj5300: [Cqoi2018]九连环(fft优化高精+快速幂)
传送门 题意不好描述(自己看样例解释) 首先可以推出一个递推式:fn=fn−1+2fn−2+1f_n=f_{n-1}+2f_{n-2}+1fn=fn−1+2fn−2+1 然后可以构造两个等式: ...
- BZOJ5300 [Cqoi2018]九连环 【dp + 高精】
题目链接 BZOJ5300 题解 这题真的是很丧病,,卡高精卡到哭 我们设\(f[i]\)表示卸掉前\(i\)个环需要的步数 那么 \[f[i] = 2*f[i - 2] + f[i - 1] + 1 ...
- CQOI2018 九连环 打表找规律 fft快速傅里叶变换
题面: CQOI2018九连环 分析: 个人认为这道题没有什么价值,纯粹是为了考算法而考算法. 对于小数据我们可以直接爆搜打表,打表出来我们可以观察规律. f[1~10]: 1 2 5 10 21 4 ...
- CQOI2018简要题解
CQOI2018简要题解 D1T1 破解 D-H 协议 题意 Diffie-Hellman 密钥交换协议是一种简单有效的密钥交换方法.它可以让通讯双方在没有事先约定密钥(密码)的情况下,通过不安全的信 ...
- 高精度&&FFT
ACM-高精度模板(综合篇) 时间:-- :: 阅读: 评论: 收藏: [点我收藏+] 标签:高精度 在这里,我们约定,能用int表示的数据视为单精度,否则为高精度.所有函数的设计均采用带返回值的形式 ...
- CQOI2018 简要题解
破解D-H协议 列个式子会发现是BSGSBSGSBSGS的模板题,直接码就是了. 代码: #include<bits/stdc++.h> #include<tr1/unordered ...
随机推荐
- (转)Putty server refused our key的三种原因和解决方法
原文 上一篇博文介绍了使用Putty免密码登录,我后面试了另一台虚拟机,结果putty显示错误server refused our key(在linux下则表现为仍需要输入密码),搜索了下,很多人都遇 ...
- k-means+python︱scikit-learn中的KMeans聚类实现( + MiniBatchKMeans)
来源:, init='k-means++', n_init=10, max_iter=300, tol=0.0001, precompute_distances='auto', verbose=0, ...
- Bayesian Personalized Ranking 算法解析及Python实现
1. Learning to Rank 1.1 什么是排序算法 为什么google搜索 ”idiot“ 后,会出现特朗普的照片? “我们已经爬取和存储了数十亿的网页拷贝在我们相应的索引位置.因此,你输 ...
- OpenTK教程-2绘制一个三角形(正确的方式)
上一个教程向我们展示了如何在屏幕上画一个三角形.但是,我说过,那是一种古老的方式,即使它能够正常运行,但是现在这已经不是"正确"的方式.上篇文章中我们将几何发送到GPU的方式是所谓 ...
- 2018年高教社杯全国大学生数学建模竞赛B题解题思路
题目 先贴下B题的题目吧 问题B 智能RGV的动态调度策略 图1是一个智能加工系统的示意图,由8台计算机数控机床(Computer Number Controller,CNC).1辆轨道式自动引 ...
- CrackMe005-下篇 | 逆向破解分析 | 160个CrackMe(视频+图文)深度解析系列
作者:逆向驿站微信公众号:逆向驿站知乎:逆向驿站 CrackMe005,上篇说了具体方法,下篇来发逆向分析过程,看看老夫是如何得到上篇的具体方法的! 准备 [环境和工具] win7/xp虚拟机环境 C ...
- 《Linux内核设计与实现》读书笔记 4 进程调度
第四章进程调度 进程调度程序可看做在可运行太进程之间分配有限的处理器时间资源的内核子系统.调度程序是多任务操作系统的基础.通过调度程序的合理调度,系统资源才能最大限度地发挥作用,多进程才会有并发执行的 ...
- Practice2 结对子之“小学四则运算”
开发环境:Eclipse,js,css,html 程序完成的方向: 1.可以出表达式里含有负整数(负整数最小不小于-100)的题目,且负数需要带括号,用户输入的结果不用带括号.如: 2*(-4) = ...
- 数学战神app(小学生四则运算app)开发需求及进度
项目名字:“数学战神” 开发环境:Android eclipse 团队名称:战神联盟 团队成员:陈思明,许家豪,王宏财,吴旭涛 在之前的四则运算APP中添加更多的实用功能,并在各种平台推广宣传. 预加 ...
- 修复PLSQL Developer 与 Office 2010的集成导出Excel 功能
Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\.htm]"PerceivedType"="text&qu ...