#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <limits.h>
#define EPS 1e-9 //浮点比较
#define MOD 998244353 //取模运算
#define MAX_LL 1000010//大型数组
#define MAX_L 1010 //小型数组
#define MAX_N 11 //矩阵阶数
#define PI 3.141592653//通用常数
#define EU 2.718281828//通用常数
#define in int
#define ll long long
#define fl float
#define db double
#define ch char
#define vd void
#define br break
#define cn continue
#define rt return
#define sc scanf
#define pr printf
//支持单元输入
#define scin(x) sc("%d", &(x))
#define scll(x) sc("%lld", &(x))
#define scdb(x) sc("%lf", &(x))
//支持空白略去
#define scch(x) sc(" %c", &(x))
#define scst(x) sc(" %s", (x))
//支持二元输入
#define scin2(x,y) sc("%d%d", &(x), &(y))
#define scll2(x,y) sc("%lld%lld", &(x), &(y))
#define scdb2(x,y) sc("%lf%lf", &(x), &(y))
//支持一元输出
#define prin(x) pr("%d", x)
#define prll(x) pr("%lld", x)
#define prdb(x) pr("%lf", x)
#define prch(x) pr("%c", x)
#define prst(x) pr("%s", x)
//支持一元换行输出
#define prinn(x) pr("%d\n", x)
#define prlln(x) pr("%lld\n", x)
#define prdbn(x) pr("%lf\n", x)
#define prchn(x) pr("%c\n", x)
#define prstn(x) pr("%s\n", x)
//支持一元精度输出
#define prdbr(x, r) pr("%.*lf", (r), (x))
//支持一元精度换行输出
#define prdbnr(x, r) pr("%.*lf\n", (r), (x))
//支持换行输出
#define prn pr("\n")
//支持空格输出
#define prb pr(" ")
//支持浮点相等判断
#define CEPS(a, b) (fabs((a) - (b)) < EPS)
//函数主体
//输入输出辅助
//高效输入(大量数据读取)
in fast_read()
{
in x = 0, f = 1;
ch c = getchar();
while (c < '0' || c > '9')
{
if (c == '-') f = -f;
c = getchar();
}
while (c >= '0' && c <= '9')
{
x = x * 10 + c - '0';
c = getchar();
}
rt x* f;
}
//辅助一维数组输入([0,n))
vd sc_arr1(in arr[], in n)
{
for (in i = 0; i < n; i++)
{
scin(arr[i]);
}
}
//辅助一维数组输出([0,n))(自动去除换行符号)
vd pr_arr1(in arr[], in n)
{
for (in i = 0; i < n; i++)
{
pr("%d%c ", arr[i], " \n"[i == n - 1]);
}
}
//辅助二维数组输入([0,n))
vd sc_arr2(in arr[][MAX_N], in row, in col)
{
for (in i = 0; i < row; i++)
{
for (in j = 0; j < col; j++)
{
while ((scin(arr[i][j])) != 1)
{
while (getchar() != ' ');
}
}
}
}
//辅助二维数组输出([0,n))
vd pr_arr2(in arr[][MAX_N], in row, in col)
{
for (in i = 0; i < row; i++)
{
for (in j = 0; j < col; j++)
{
pr("%d ", arr[i][j]);
}
pr("\n");
}
}
//基础数学计算
//计算斐波那契数列第n个数(非递归)
ll fibonacci1(in n)
{
if (n == 0) rt 0;
if (n == 1) rt 1;
ll prev = 0;
ll curr = 1;
ll next;
for (in i = 2; i <= n; i++)
{
next = prev + curr;
prev = curr;
curr = next;
}
rt curr;
}
//计算斐波那契数列第n个数(仅递归)
ll fibonacci2(in n)
{
if (n == 0)
{
rt 0;
}
else if (n == 1 || n == 2)
{
rt 1;
}
rt fibonacci2(n - 1) + fibonacci2(n - 2);
}
//计算斐波那契数列第n个数(递归;预存储;重复调用;取模;小n;越界MAX_L#-1)
ll mem[MAX_L] = { 0 };in vis[MAX_L] = { 0 };
vd reset()
{//初始化记忆数组
memset(vis, 0, sizeof(vis));
}
ll fibonacci_mem(in n)
{//(嵌mod_add)
if (n < 0 || n >= MAX_L)
rt -1;
if (n == 0)
rt 0;
if (n == 1)
rt 1;
if (vis[n])
rt mem[n];
mem[n] = mod_add(fibonacci_mem(n - 1), fibonacci_mem(n - 2));
vis[n] = 1;
rt mem[n];
}
//计算斐波那契数列第n个数(迭代;非存储;单次调用;取模;大n;越界MAX_L#-1)
ll fib_iterative(in n)
{
if (n < 0 || n >= MAX_L)
return -1;
if (n == 0) return 0;
if (n == 1) return 1;
ll f0 = 0, f1 = 1;
for (in i = 2; i <= n; ++i)
{
ll f2 = mod_add(f0, f1);
f0 = f1;
f1 = f2;
}
return f1;
}
//计算给定数n的阶乘(非递归;取模;错误#-1)
ll factorial1(in n)
{
if (n < 0)
rt - 1;
ll result = 1;
for (in i = 2; i <= n; i++)
{
result = ((result % MOD) * (i % MOD)) % MOD;
}
rt result;
}
//计算给定数n的阶乘(仅递归;取模)
ll factorial2(in n)
{
if (n <= 1)
{
rt 1;
}
rt((n % MOD) * (factorial2(n - 1) % MOD)) % MOD;
}
//计算排列数P(对n排k;取模;错误#-1)
ll Per(in n, in k)
{
if (k < 0 || n < 0 || k > n)
{
rt - 1;
}
ll result = 1;
for (in i = n - k + 1; i <= n; i++)
{
result = (result * i) % MOD;
}
rt result;
}
//计算组合数C(对n组k;特殊;错误#-1)
ll Com_sp(in n, in k)
{
if (k < 0 || n < 0 || k > n)
{
rt - 1;
}
if (k > n - k)
{
k = n - k;
}
ll result = 1;
for (in i = 0; i < k; i++)
{
result = result * (static_cast<long long>(n) - i) / (static_cast<long long>(i) + 1);
}
rt result;
}
//计算幂次(快速幂)(base的exp次方;取模)
ll pow_mod(ll base, ll exp)
{
ll result = 1;
while (exp > 0)
{
if (exp & 1)
{
result = (result * base) % MOD;
}
base = (base * base) % MOD;
exp >>= 1;
}
rt result;
}
//计算二元最大公因数(绝对值)
ll gcd2(ll a, ll b)
{
if (a < 0)
a = -a;
if (b < 0)
b = -b;
while (b != 0)
{
ll temp = b;
b = a % b;
a = temp;
}
rt a;
}
//计算三元最大公因数(嵌gcd2)
ll gcd3(ll a, ll b, ll c)
{
rt gcd2(gcd2(a, b), c);
}
//计算n元最大公因数(数组[1,n);嵌gcd2)
ll gcdn(ll arr[], in n)
{
if (n == 0) rt 0;
ll result = arr[0];
for (in i = 1; i < n; ++i)
{
result = gcd2(result, arr[i]);
if (result == 1) br;
}
rt result;
}
//计算二元最小公倍数(嵌gcd2)
ll lcm2(ll a, ll b)
{
if (a == 0 || b == 0) rt 0;
ll ga = a < 0 ? -a : a;
ll gb = b < 0 ? -b : b;
ll g = gcd2(ga, gb);
rt ga / g * gb;
}
//计算三元最小公倍数(嵌lcm2)
ll lcm3(ll a, ll b, ll c)
{
rt lcm2(lcm2(a, b), c);
}
//计算n元最小公倍数(数组[1,n);嵌lcm2)
ll lcmn(ll arr[], in n)
{
if (n == 0) rt 1;
ll result = arr[0];
for (in i = 1; i < n; ++i)
{
result = lcm2(result, arr[i]);
if (result == 0) br;
}
rt result;
}
//计算n元最小公倍数(数组[1,n);嵌lcm2;取模)
ll lcmn_mod(ll arr[], in n)
{
if (n == 0) rt 1;
ll result = arr[0];
for (in i = 1; i < n; ++i)
{
result = lcm2(result, arr[i]);
if (result == 0) br;
result %= MOD;
}
rt result;
}
//计算模加法/减法
ll norm(ll x)
{//工具函数(映射到[0,MOD-1];处理负数)
rt (x % MOD + MOD) % MOD;
}
ll mod_add(ll a, ll b)
{//模加法
rt norm(a + b);
}
ll mod_sub(ll a, ll b)
{//模减法
rt norm(a - b);
}
//计算模乘法(快速版)
ll mod_qmul(ll a, ll b)
{
a %= MOD;
b %= MOD;
ll res = 0;
while (b > 0)
{
if (b & 1)
{
res = (res + a) % MOD;
}
a = (a << 1) % MOD;
b >>= 1;
}
rt res;
}
//计算模乘法(基础版)
ll mod_fmul(ll a, ll b)
{
rt ((a % MOD) * (b % MOD)) % MOD;
}
//基础数学判断
//判断x是否为回文数(是#1;否#0)
in is_palindrome(in x)
{
if (x < 0) rt 0;
in original = x;
in reversed = 0;
while (x > 0)
{
reversed = reversed * 10 + x % 10;
x /= 10;
}
rt original == reversed;
}
//判断x是否为斐波那契数(是#1;否#0)
in is_fibonacci(in x)
{
if (x < 0) rt 0;
if (x == 0 || x == 1) rt 1;
in a = 0, b = 1;
while (b < x)
{
in next = a + b;
a = b;
b = next;
}
rt b == x;
}
//判断x是否为阶乘数(是#1;否#0)
in is_factorial(in x)
{
if (x <= 0) rt 0;
in fact = 1;
for (in i = 1; ; ++i)
{
fact *= i;
if (fact == x) rt 1;
if (fact > x) rt 0;
}
}
//判断x是否为完全平方数(是#1;否#0)
in is_psquare(in x)
{
if (x < 0) rt 0;
in root = (in)sqrt((long double)x) + 0.5;
rt root* root == x;
}
//判断x是否为素数(是#1;否#0)
in is_prime(in x)
{
if (x <= 1)
{
rt 0;
}
else if (x <= 3)
{
rt 1;
}
else if (x % 2 == 0 || x % 3 == 0)
{
rt 0;
}
for (in i = 5; i * i <= x; i += 6)
{
if (x % i == 0 || x % (i + 2) == 0)
{
rt 0;
}
}
rt 1;
}
//判断x是否为2的自然数幂次(是#1;否#0)
in is_power2(in x)
{
rt x > 0 && (x & (x - 1)) == 0;
}
//任意进制转换
//10进制转2进制(正数;数字转数字版)
ll to_bin(ll n)
{
if (n == 0) rt 0LL;
ll bin = 0;
ll base = 1;
while (n > 0)
{
bin += (n % 2) * base;
n /= 2;
base *= 10;
}
rt bin;
}
//10进制转2进制(正数;数字转数组版;存入arr;低位在前;#二进制位数>0)
in to_bin_arrl(ll n, in arr[])
{
if (n == 0)
{
arr[0] = 0;
rt 1;
}
in i = 0;
while (n > 0)
{
arr[i++] = n % 2;
n /= 2;
}
rt i;
}
//10进制转2进制(正数;数字转数组版;存入arr;高位在前;#二进制位数>0)
in to_bin_arrh(ll n, in arr[])
{
if (n == 0)
{
arr[0] = 0;
rt 1;
}
in temp[64];
in len = 0;
while (n > 0)
{
temp[len++] = n % 2;
n /= 2;
}
for (in i = 0; i < len; ++i)
{
arr[i] = temp[len - 1 - i];
}
rt len;
}
//10进制转2进制(正数;数组转数组版;len位dec;存入bin;低位在前;#二进制位数>0)
in to_bin_2arrl(in dec[], in bin[], in len)
{
in work[MAX_L];
in temp[MAX_L];
in bin_len = 0;
for (in i = 0; i < len; ++i)
{
work[i] = dec[i];
}
while (1)
{
in all_zero = 1;
for (in i = 0; i < len; ++i)
{
if (work[i] != 0)
{
all_zero = 0;
br;
}
}
if (all_zero) rt bin_len;
in carry = 0;
for (in i = 0; i < len; ++i)
{
carry = carry * 10 + work[i];
temp[i] = carry / 2;
carry %= 2;
}
bin[bin_len++] = carry;
for (in i = 0; i < len; ++i)
{
work[i] = temp[i];
}
}
}
//10进制转2进制(正数;数组转数组版;len位dec;存入bin;高位在前;#二进制位数>0)
in to_bin_2arrh(in dec[], in bin[], in len)
{
in work[MAX_L];
in temp[MAX_L];
in bits[MAX_L];
in bit_len = 0;
for (in i = 0; i < len; ++i)
{
work[i] = dec[i];
}
while (1)
{
in all_zero = 1;
for (in i = 0; i < len; ++i)
{
if (work[i] != 0)
{
all_zero = 0;
br;
}
}
if (all_zero) br;
in carry = 0;
for (in i = 0; i < len; ++i)
{
carry = carry * 10 + work[i];
temp[i] = carry / 2;
carry %= 2;
}
bits[bit_len++] = carry;
for (in i = 0; i < len; ++i)
{
work[i] = temp[i];
}
}
if (bit_len == 0)
{
bin[0] = 0;
rt 1;
}
for (in i = 0; i < bit_len; ++i)
{
bin[i] = bits[bit_len - 1 - i];
}
rt bit_len;
}
//10进制转2进制(正数;数串转数组版;串num_str;存入bin;低位在前;#二进制位数>0)
in str_to_dgt1(const char* str, in digits[])
{//Tool.字符串转数组(#有效长度)
in len = 0;
while (str[len] != '\0')
{
if (str[len] >= '0' && str[len] <= '9')
digits[len] = str[len] - '0';
else
br;
++len;
}
rt len;
}
in to_bin_strl(const char* num_str, in bin[])
{//Main.数串转数组(#二进制位数)(嵌str_to_dgt1,to_bin_2arrl)
if (num_str == NULL || *num_str == '\0')
{
bin[0] = 0;
rt 1;
}
in digits[MAX_L];
in d_len = str_to_dgt1(num_str, digits);
in all_zero = 1;
for (in i = 0; i < d_len; ++i)
{
if (digits[i] != 0)
{
all_zero = 0;
br;
}
}
if (all_zero)
{
bin[0] = 0;
rt 1;
}
rt to_bin_2arrl(digits, bin, d_len);
}
//10进制转2进制(正数;数串转数组版;串num_str;存入bin;高位在前;#二进制位数>0)
in str_to_dgt2(const char* str, in digits[])
{//Tool.字符串转数组(#有效长度)
in len = 0;
while (str[len] != '\0')
{
if (str[len] >= '0' && str[len] <= '9')
digits[len] = str[len] - '0';
else
br;
++len;
}
rt len;
}
in to_bin_strh(const char* num_str, in bin[])
{//Main.数串转数组(#二进制位数)(嵌str_to_dgt2,to_bin_2arrh)
if (num_str == NULL || *num_str == '\0')
{
bin[0] = 0;
rt 1;
}
in digits[MAX_L];
in d_len = str_to_dgt2(num_str, digits);
in all_zero = 1;
for (in i = 0; i < d_len; ++i)
{
if (digits[i] != 0)
{
all_zero = 0;
br;
}
}
if (all_zero)
{
bin[0] = 0;
rt 1;
}
rt to_bin_2arrh(digits, bin, d_len);
}
//任意进制转换(2~36间;正数;字符串n转字符组m;错误#-1;正确#0(可忽略rt))
in char_to_value(ch c)
{//Tool.字符转数字
if (isdigit(c)) rt c - '0';
if (isupper(c)) rt c - 'A' + 10;
if (islower(c)) rt c - 'a' + 10;
rt - 1;
}
ch value_to_char(in val)
{//Tool.数字转字符
if (val < 10) rt '0' + val;
rt 'A' + val - 10;
}
in convert_base(const ch* n, in a, in b, ch m[])
{//Main.任意进制转换(嵌char_to_value,value_to_char)
if (!n || !m || a < 2 || a > 36 || b < 2 || b > 36)
{
if (m) m[0] = '\0';
rt - 1;
}
in len = strlen(n);
if (len == 0)
{
m[0] = '0'; m[1] = '\0';
rt 0;
}
ll decimal = 0;
for (in i = 0; i < len; ++i)
{
in val = char_to_value(n[i]);
if (val == -1 || val >= a)
{
m[0] = '\0';
rt - 1;
}
if (decimal > (LLONG_MAX - val) / a)
{
m[0] = '\0';
rt - 1;
}
decimal = decimal * a + val;
}
if (decimal == 0)
{
m[0] = '0';
m[1] = '\0';
rt 0;
}
ch temp[65];
in idx = 0;
while (decimal > 0)
{
in r = decimal % b;
temp[idx++] = value_to_char(r);
decimal /= b;
}
temp[idx] = '\0';
for (in i = 0; i < idx; ++i)
{
m[i] = temp[idx - 1 - i];
}
m[idx] = '\0';
rt 0;
}
最新发布