//前传
//这题复杂度不会算...
//哦T了啊 那没事了
//一般来讲每次乘是等于位数的 然后要乘P次
//但是1e6 * 3.1e7显然会T飞掉
//然后想到用快速幂优化 3.1e7开log可以变成25左右
//但是每次乘复杂度就会变成位数的平方
//假设P取max值 则答案有1e6位
//那么最后一次乘应该是三位数*三位数
//诶好像能过
//但是我不会多位数*多位数的高精 开香槟!
//交个暴力上去罢 看看能嫖多少分
//别暴力都写挂了啊 我害怕((
//来点快速幂板子
//int ksm(int x, int k) {
// int res = 1;
// while (k) {
// if (k & 1) res *= x;
// x *= x;
// k >>= 1;
// }
// return res;
//}
//这玩意应该不能写挂吧/fad
//#include <bits/stdc++.h>
//#define ll long long
//using namespace std;
//
//const int N = 1e6 + 0721;
//int a[N];
//int wei = 1;
//ll P;
//
//void ch(void) {
// for (int i = 1; i <= wei; ++i) a[i] <<= 1;
// for (int i = 1; i <= wei; ++i) {
// a[i + 1] += a[i] / 10;
// a[i] %= 10;
// }
// if (a[wei + 1] != 0) ++wei;
//}
//
//void minu(void) {
// --a[1];
// for (int i = 1; i <= wei; ++i) {
// if (a[i] == -1) {
// a[i] = 9;
// --a[i + 1];
// }
// else
// break;
// }
// while (a[wei] == 0) --wei; //直接写if好像也行
//}
//
//int main() {
// freopen("mason.in", "r", stdin);
// freopen("mason.out", "w", stdout);
//
// scanf("%lld", &P);
//
// a[1] = 1;
// while(P--) {
// cout<<"1";
// ch();
// }
// minu();
//
// printf("%d\n",wei);
// int cont = 0;
// for (int i = 500; i >= 1; --i) {
// if (cont == 50) {
// printf("\n");
// cont = 0;
// }
// printf("%d",a[i]);
// ++cont;
// }
//
// return 0;
//}
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6 + 0721;
ll res[N], x[N], tmp[N];
ll P;
int wres = 1, wx = 1;
void ch1(void) { //x*x的
for (int i = 1; i <= 1e6; ++i) tmp[i] = 0;
for (int i = 1; i <= wx; ++i) {
for (int j = 1; j <= wx; ++j) tmp[i + j - 1] += x[i] * x[j];
}
int maxlen = wx + wx - 1;
// cout<<maxlen<<endl;
// for (int i = maxlen; i >= 1; --i) cout<<tmp[i];
// cout<<endl;
for (int i = 1; i <= maxlen; ++i) {
tmp[i + 1] += tmp[i] / 10;
tmp[i] = tmp[i] % 10;
x[i] = tmp[i];
}
x[maxlen + 1] = tmp[maxlen + 1];
while (x[maxlen + 1] != 0) ++maxlen;
// for (int i = maxlen; i >= 1; --i) cout<<tmp[i];
// cout<<endl;
wx = maxlen;
}
void ch2(void) { //res*x的
for (int i = 1; i <= 1e6; ++i) tmp[i] = 0;
for (int i = 1; i <= wx; ++i) {
for (int j = 1; j <= wres; ++j) tmp[i + j - 1] += x[i] * res[j];
}
int maxlen = wx + wres - 1;
for (int i = 1; i <= maxlen; ++i) {
tmp[i + 1] += tmp[i] / 10;
tmp[i] %= 10;
res[i] = tmp[i];
}
res[maxlen + 1] = tmp[maxlen + 1];
while (res[maxlen + 1] != 0) ++maxlen;
wres = maxlen;
}
void ksm(ll k) {
res[1] = 1;
x[1] = 2;
while (k) {
if (k & 1) ch2();
ch1();
k >>= 1;
}
}
void minu(void) { //才发现因为一直是2相乘所以个位必不可能是0直接减就行 但是我懒得改了(
--res[1];
for (int i = 1; i <= wres; ++i) {
if (res[i] == -1) {
res[i] = 9;
--res[i + 1];
}
else
break;
}
while (res[wres] == 0) --wres;
}
int main() {
freopen("mason.in", "r", stdin);
freopen("mason.out", "w", stdout);
scanf("%lld", &P);
ksm(P);
minu();
printf("%d\n",wres);
int cont = 0;
for (int i = 500; i >= 1; --i) {
if (cont == 50) {
printf("\n");
cont = 0;
}
printf("%d",res[i]);
++cont;
}
return 0;
}
//淦怎么又T了 不会了开摆!
//诶不是这时间怎么差不多啊...麻了...
tnnd 为什么没想到lg n 就是 n 的位数!
标签:cont,int,res,void,--,无题,ll From: https://www.cnblogs.com/Steven24/p/17316583.html