/*****************
数学整理
*****************/
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e6+5;
//< 1 > 大数 (Java)
/*******
import java.util.*;
import java.math.*;
import java.lang.*;
public class Main{
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner cin = new Scanner(System.in);
int b;
while(cin.hasNext()){
String s=cin.next();
BigDecimal a=new BigDecimal(s);
b=cin.nextInt();
BigDecimal n=a.pow(b);
String ans=n.stripTrailingZeros().toPlainString();
if(ans.startsWith("0"))ans=ans.substring(1);
System.out.println(ans);
}
}
}
*******/
/*
注意:使用java大数类解决问题时我们需要注意两个方面
1、不能有包名,也就是说我们要把主类放到默认的包里,
2、提交的类的类名必须为Main,如果是其他的名字你有可能收获到CE也有可能收获到WA
*/
/************************************
1、新建一个值为123的大整数对象
BigInteger a=new BigInteger(“123”); //第一种,参数是字符串
BigInteger a=BigInteger.valueOf(123); //第二种,参数可以是int、long
2、大整数的四则运算
a. add(b); //a,b均为BigInteger类型,加法
a.subtract(b); //减 法
a.divide(b); //除法
a.multiply(b); //乘法
3、大整数比较大小
a.equals(b); //如果a、b相等返回true否则返回false
a.compareTo(b); //a小于b返回-1,等于返回0,大于返回1
4、常用方法
a.mod(b); //求余
a.gcd(b); //求最大公约数
a.max(b); //求最大值
a.min(b); //求最小值
a.pow(n); //求a的n次方 (n : int)
5、BigInteger中的常数
BigInteger.ZERO //大整数0
BigInteger.ONE //大整数1
BigInteger.TEN //大整数10
6、求大整数的位数
//先转换成字符串再求字符串的长度
a.toString().length(); //a的类型为BigInteger
//------------------
输入框架
场景一:不断读入数据直至文件尾,或者说有多组测试用例以EOF为结束标志
Scanner cin = new Scanner(System.in); //相当于C++中的cin,只不过这个cin需要自己创建
while(cin.hasNext()){ //等同于!=EOF
BigInteger a;
BigDecimal b;
a = cin.nextBigInteger(); //读入一个BigInteger;
b = cin.nextBigDecimal(); //读入一个BigDecimal;
System.out.println(a); //输出a并换行
}
场景二:输入一个整数T,代表有T组测试样例
Scanner cin = new Scanner(System.in);
int T = cin.nextInt();
while (T-- > 0) {
String s = cin.next();
BigInteger a = new BigInteger(s);
System.out.println(a.toString());
}
******************/
//< 2 > 快速乘/幂
ll mul(ll a, ll b, ll mod) {
ll res = 0;
while (b > 0) {
if (b & 1) res = (res + a) % mod;
b = b >> 1;
a = a + a % mod;
}
return res;
}
ll qpow(ll a, ll b, ll mod) {
ll res = 1;
while (b > 0) {
if (b & 1) res = mul(res, a, mod);
b = b >> 1;
a = mul(a, a, mod);
}
return res;
}
//光速幂
//a[n] = 233 a[n - 1] + 666 a[n - 2]
/*
1.列出特征方程,解方程。得到x1,x2;
2.a[n] = k1 * x1 ^ n + k2 * x2 ^ n;代入n=0,1求得k1,k2;
3.去除k1,k2中的无理数(暴力或是欧拉均可)
4.得到a[n] = k * (p ^ n - q ^ n)
5.里面两个底数的n次方如何O(1)求?分段打表
Mod :模数 alpha : k
x_1 :p x_2 : q
x_3 :qpow(x_1, 65536, Mod)
x_4 :qpow(x_2, 65536, Mod)
*/
namespace Maker {
unsigned long long SA, SB, SC;
void init() {
scanf("%llu%llu%llu", &SA, &SB, &SC);
}
inline unsigned long long rand() {
SA ^= SA << 32, SA ^= SA >> 13, SA ^= SA << 1;
unsigned long long t = SA;
SA = SB, SB = SC, SC ^= t ^ SA;
return SC;
}
}
const int Mod = 1e9 + 7;
const int alpha = 233230706;
const int x_1 = 94153035;
const int x_2 = 905847205;
const int x_3 = 64353223;
const int x_4 = 847809841;
const int maxn = 65536 + 5;
int f_1[maxn], f_2[maxn], f_3[maxn], f_4[maxn], T, ans;
inline int Pow_1(int x) {
return 1ll * f_3[x >> 16] * f_1[x & 65535] % Mod;
}
inline int Pow_2(int x) {
return 1ll * f_4[x >> 16] * f_2[x & 65535] % Mod;
}
int main() {
f_1[0] = f_2[0] = f_3[0] = f_4[0] = 1;
for(int i = 1; i < 65536; i++) f_1[i] = 1ll * f_1[i - 1] * x_1 % Mod;
for(int i = 1; i < 65536; i++) f_2[i] = 1ll * f_2[i - 1] * x_2 % Mod;
for(int i = 1; i < 65536; i++) f_3[i] = 1ll * f_3[i - 1] * x_3 % Mod;
for(int i = 1; i < 65536; i++) f_4[i] = 1ll * f_4[i - 1] * x_4 % Mod;
scanf("%d", &T);
Maker::init();
unsigned long long n;
while(T--) {
//欧拉降幂
n = Maker::rand() % (Mod - 1);
ans ^= 1ll * alpha * (Pow_1(n) - Pow_2(n) + Mod) % Mod;
}
printf("%d\n", ans);
return 0;
}
//< 3 > 筛法 && 素数
//反素数
void dfs(int dep,ll tmp,int num,int limit) { //dep表示到第几个素数,
//tmp表示当前可能ans值,num表示因子数
if(dep>=16) return;//深度达到最大
if(num>best) { //best记的是当前最优num,有更优就更新
best=num;
ans=tmp;
}
//当因子个数相同时,取值最小的
if(num==best&&ans>tmp) ans=tmp;
for(int i=1; i<=limit; i++) {
if(n/p[dep]<tmp) break;
dfs(dep+1,tmp*=p[dept],num*(i+1));
}
}
//欧拉筛法 素数筛 O(n)
int Euler_shai() {
int tot = 0;
int n = 1e3+1;
memset(check, 0, sizeof check);
for(int i = 2; i <= n; ++i) {
if(!check[i]) {
pri[tot++] = i;
}
for(int j = 1; j < tot; ++j) {
if(i * pri[j] > n) break;
check[i * pri[j]] = 1 ;
if(i % pri[j] == 0) break;
}
}
}
//大素数测试
bool Miller_Rabin(ll n) { //Miller_Rabin
ll t,u,s = 10;
if(n == 2 || n == 3) return true;
if(n < 2 || !(n & 1)) return false;
for(t = 0,u = n-1; !(u&1); t++, u >>= 1); //n-1 = u*2^t
for(int i = 0; i < s; i++) {
ll a = rand() % (n - 1) - 1;
ll x = qpow(a, u, n); //a^u
for(ll j = 0; j < t; j++) {
ll y = mul(x, x, n); //x^2
if(y == 1 && x != 1 && x != n-1) return false; //二次探测
x = y;
}
if(x != 1) return false; //费马小定理
}
return true;
}
//大整数分解
ll Pollard_Rho(ll n,ll c) {
ll i = 1, j = 2;
ll x = rand() % (n - 1) + 1, y = x;//随机初始化一个基数(p1)
while(1) {
i++;
x=(mul(x, x, n) + c) % n;//玄学递推
ll p = gcd((y - x + n) % n, n);
if(p != 1&&p != n) return p;//判断
if(y == x)return n;//y为x的备份,相等则说明遇到圈,退出
if(i == j) {
y = x;
j <<= 1;
}//更新y,判圈算法应用
}
}
vector <ll> ans;
void find(ll n,ll c) { //同上,n为待分解数,c为随机常数
if(n == 1) return;
if(Miller_Rabin(n)) { //n为质数
ans.push_back(n);
return;
}
ll x = n, k = c;
while(x==n)
x = Pollard_Rho(x, c--);//当未分解成功时,换个c带入算法
find(n/x, k);
find(x, k); //递归操作
}
//因子数
ll Divisors_num(ll n, int tot) { //素数总数
ll ans = 1;
for(int i = 0; i < tot && prime[i] * prime[i] <= n; i++) {
if(n % prime[i] == 0) {
int cnt = 0;
while(n % prime[i] == 0) {
cnt++;
n /= prime[i];
}
ans *= (cnt + 1);
}
}
if(n > 1)ans *= 2;
return ans;
}
//因子和
ll Divisors_sum(ll n, int tot) {
ll ans = 1;
for(int i = 0; i < tot && prime[i] * prime[i] <= n; i++) {
if(n % prime[i] == 0) {
int cnt = 0;
while(n % prime[i] == 0) {
cnt++;
n /= prime[i];
}
ans = (qpow(prime[i], cnt + 1) - 1) / (prime[i] - 1) * ans;
}
}
if(n > 1)ans *= (n + 1);
return ans;
}
//大数区间素数筛法 [L,R] O(n)
vector <ll> getprime(ll n, ll m) {
vector <ll> pri;
bitset <maxn> used(0), rused(0);
ll len = sqrt(m);
for(int i = 2; i <= len; ++i) {
if(!used[i]) {
ll x = i, y = max(x, x * (n / x));
while(y <= m) {
if(y - n >= 0 && y != x)
rused[y - n] = true;
y += x;
}
for(int j = 2 * i; j <= len; j += i) {
used[j] = true;
}
}
}
for(int i = 0; i <= m - n; ++i) {
if(i + n >= 2 && !rused[i])
pri.push_back(i + n);
}
return pri;
}
//欧拉 函数打表
void phi_table(int n, int* phi) {
for (int i = 2; i <= n; i++) phi[i] = 0;
phi[1] = 1;
for (int i = 2; i <= n; i++)
if (!phi[i])
for (int j = i; j <= n; j += i) {
if (!phi[j]) phi[j] = j;
phi[j] = phi[j] / i * (i - 1);
}
}
//求单个欧拉函数
int euler_phi(int n) {
int m = (int)sqrt(n + 0.5);
int ans = n;
for(int i = 2; i <= m; i++)if(n % i == 0) {
ans = ans / i * (i - 1);
while(n % i == 0)n /= i;
}
if(n > 1)ans = ans / n * (n - 1);
return ans;
}
//莫比乌斯筛法
void pre() {
mu[1] = 1;
for (int i = 2; i <= 1e7; ++i) {
if (!v[i]) mu[i] = -1, p[++tot] = i;
for (int j = 1; j <= tot && i <= 1e7 / p[j]; ++j) {
v[i * p[j]] = 1;
if (i % p[j] == 0) {
mu[i * p[j]] = 0;
break;
}
mu[i * p[j]] = -mu[i];
}
}
}
//< 3 > 同余与同余方程
//辗转相除法 求最大公约数
ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a % b);
}
//Stein算法 求最大公约数
int SteinGCD(int a, int b) {
if (a < b) {
int t = a;
a = b;
b = t;
}
if (b == 0) return a;
if ((a & 1) == 0 && (b & 1) == 0)
return SteinGCD(a >> 1, b >> 1) << 1;
else if ((a & 1) == 0 && (b & 1) != 0)
return SteinGCD(a >> 1, b);
else if ((a & 1) != 0 && (b & 1) == 0)
return SteinGCD(a, b >> 1);
else
return SteinGCD(a - b, b);
}
//求解ax+by=gcd(a, b)
//返回值为gcd(a, b)
ll extgcd(ll a, ll b, ll& x, ll& y) {
ll d = a;
if(b) {
d = extgcd(b, a % b, y, x);
y -= (a / b) * x;
} else x = 1, y = 0;
return d;
}
//求解a关于模上m的逆元
//返回-1表示逆元不存在
ll mod_inverse(ll a, ll m) {
ll x, y;
ll d = extgcd(a, m, x, y);
return d == 1 ? (m + x % m) % m : -1;
}
//快速幂费马小定理求逆元
ll mod_inverse2(ll a, ll m) { //m是素数,a的逆元就是a的m-2次方
return qpow(a, m - 2, m);
}
/****************
逆元不存在,求解 a / b mod k(前提:b | a)
逆元存在时,a / b mod k 等价于a * B mod k(B是b模上k的逆元)
但是逆元不存在时:通用公式:a / b mod k = a mod(k * b) / b
---------------------------------------------
费马小定理和扩展欧几里得算法求逆元是有局限性的,
它们都会要求a和m互素(此处的a和m是之前ax = 1(mod m)中的a和m,
在这里应该是这里的b和m互素
****************/
//线性求逆元
int inv[10010]; //从1到n的逆元
void init(int n) {
inv[1] = 1;
for (int i = 2; i <= n; ++i)
inv[i] = (long long)(p - p / i) * inv[p % i] % p;
}
//线性求任意 n 个数的逆元
int a[10010]; // 要求的n个数
int s[10010]; // 前缀积
int inv1[10010]; // 第i个数的逆元
void init1(int n,int p) {
s[0] = 1;
for (int i = 1; i <= n; ++i) s[i] = s[i - 1] * a[i] % p;
long long sv[n] = mod_inverse(s[n], p);
for (int i = n; i >= 1; --i) {
inv[i] = svn * s[i - 1] % p;
svn = svn * a[i] % p;
}
}
//中国剩余定理 --> 除数两两互质
ll china(ll a[], ll m[], int n) {//a数组是余数,m数组是两两互质的数字
ll M = 1, ans = 0;
for(int i = 0; i < n; i++)M *= m[i];
for(int i = 0; i < n; i++) {
ll mi = M / m[i], x, y;
extgcd(mi, m[i], x, y);
//求出mi模上m[i]的逆元x mi * x + m[i] * y = gcd(mi, m[i]) = 1(两两互质)
ans = ans + ((a[i] % M) * (mi % M) % M) * (x % M) % M;
ans = (ans % M + M) % M;
}
return ans;
}
//扩展_中国剩余定理 --> 除数两两不一定互质
ll ex_china(ll a[], ll m[], int n) {//a数组是余数,m数组是除数
ll m0 = m[0], a0 = a[0];
for(int i = 1; i < n; i++) {
ll x, y;
ll g = extgcd(m0, m[i], x, y);//求出m0 * x + m[i] * y = gcd(x, y)
ll c = (a[i] - a0 % m[i] + m[i]) %m [i];
if(c % g)return -1;
x = mul(x , c / g , m[i] / g);
//求出m0 * x + m[i] * y = a[i] - a0的解x
//此处模上m[i]是为了取绝对值最小的一个x,因为x的通解就是x+k*m[i]
a0 = x * m0 + a0; //代回原式,求出最大的K
m0 = m0 / g * m[i]; //m0更新为m0和m[i]的lcm
a0 = ((a0 % m0) + m0) % m0;
}
return a0;
}
//< 4 > 组合数学
/************************************
n和m较大,但是p为素数的时候
Lucas定理是用来求 c(n,m) mod p,p为素数的值。
C(n,m)%p=C(n/p,m/p)*C(n%p,m%p)%p
也就是Lucas(n,m)%p=Lucas(n/p,m/p)*C(n%p,m%p)%p
***********************************/
//1, P较大,不打表:
ll C(ll n, ll m, ll p) { //组合数C(n, m) % p
if(m > n)return 0;
ll up = 1, down = 1;//分子分母;
for(int i = n - m + 1; i <= n; i++)up = up * i % p;
for(int i = 1; i <= m; i++)down = down * i % p;
return up * mod_inverse(down, p) % p;
}
ll Lucas(ll n, ll m, ll p) {
if(m == 0)return 1;
return C(n % p, m % p, p) * Lucas(n / p, m / p, p) % p;
}
//-----------------------------------------------------------
//2, P较小,打表:
const int maxn = 1e5 + 10;
ll fac[maxn];//阶乘打表
void init(ll p) {//此处的p应该小于1e5,这样Lucas定理才适用
fac[0] = 1;
for(int i = 1; i <= p; i++)
fac[i] = fac[i - 1] * i % p;
}
//组合数C(n, m) % p
ll C(ll n, ll m, ll p) {
if(m > n)return 0;
return fac[n] * mod_inverse(fac[m] * fac[n - m], p) % p;
}
//卢卡斯定理
ll Lucas(ll n, ll m, ll p) {
if(m == 0)return 1;
return C(n % p, m % p, p) * Lucas(n / p, m / p, p) % p;
}
//计算n! mod pk的部分值 pk为pi的ki次方
ll Mul(ll n, ll pi, ll pk) {
//算出的答案不包括pi的幂的那一部分
if(!n)return 1;
ll ans = 1;
if(n / pk) {
for(ll i = 2; i <= pk; i++) //求出循环节乘积
if(i % pi)ans = ans * i % pk;
ans = qpow(ans, n / pk, pk); //循环节次数为n / pk
}
for(ll i = 2; i <= n % pk; i++)
if(i % pi)ans = ans * i % pk;
return ans * Mul(n / pi, pi, pk) % pk;//递归求解
}
//计算组合数C(n, m) mod pk的值 pk为pi的ki次方
ll C(ll n, ll m, ll p, ll pi, ll pk) {
if(m > n)return 0;
ll a = Mul(n, pi, pk), b = Mul(m, pi, pk), c = Mul(n - m, pi, pk);
ll k = 0, ans;//k为pi的幂值
for(ll i = n; i; i /= pi)k += i / pi;
for(ll i = m; i; i /= pi)k -= i / pi;
for(ll i = n - m; i; i /= pi)k -= i / pi;
ans = a * mod_inverse(b, pk) % pk * mod_inverse(c, pk) % pk * pow(pi, k, pk) % pk;//ans就是n! mod pk的值
ans = ans * (p / pk) % p * mod_inverse(p / pk, pk) % p;//此时用剩余定理合并解
return ans;
}
//exLucas定理是用来求 c(n,m) mod p,p不为素数的值。
ll exLucas(ll n, ll m, ll p) {
ll x = p;
ll ans = 0;
for(ll i = 2; i <= p; i++) {
if(x % i == 0) {
ll pk = 1;
while(x % i == 0)pk *= i, x /= i;
ans = (ans + C(n, m, p, i, pk)) % p;
}
}
return ans;
}
//卡特兰数
/* 应用
1.n个数进栈,有h(n)种出栈方式;
2.凸n边形,用多条不相交的对角线分成三角形,有h(n-2)种可能性;
3.n个节点,有h(n)种不同的二叉搜索树
4.给n对括号排序,有h(n)种不同的正确的排序方式
5.买票找零n个50元,m个100元(一开始柜台没零钱)
6.n*n棋盘从左下角走到右上角而不穿过主对角线的走法
7.矩阵连乘的括号化
8.在圆上选择2n个点,将这些点成对连接起来使得所得到的n条线段不相交的方法数
9.n层阶梯矩阵切割成n个长度递增矩阵的切割法
*/
/*
递推关系: h(n)=h(n-1)*(4*n-2)/(n+1);
通项公式: h(n)=C(2n,n)/(n+1) (n=0,1,2,...)
h(n)=C(2n,n)-C(2n,n-1)(n=0,1,2,...)
进出不同(左右括号数不同)时: h(n,m)=C(n+m,n)-C(n+m,n+1)
(n代表必须先有的项数量,n>m,如左括号,入栈)
*/
const int mod = 1e9 + 7;
ll inv(ll a) {
return qpow(a,mod-2);
}
ll fac[N * 3];
void init_fac() {
fac[0] = fac[1] = 1ll;
for(int i = 2; i <= 2 * N; i++)
fac[i] = fac[i - 1] * i % mod;
}
ll C(ll a,ll b) { //组合数
if(b > a || b < 0) return 0;
return fac[a] * inv(fac[b]) % mod * inv(fac[a - b]) % mod;
}
//公式法
ll catalan(ll n) {
return (C(2 * n, n) - C(2 * n, n - 1) + mod) % mod;
}
ll catalan(ll n,ll m) { //m为大者
return (C(n + m, n) - C(n + m, n + 1) + mod) %mod;
}
//约瑟夫环
//f(n,m,k) -->
//n个人围成约瑟夫环,数到第k个数自杀,第m个死亡的人编号
//时间复杂度:O(m)
ll f(ll n,ll m,ll k){
if(m==1)return (k-1)%n;
return (f(n-1,m-1,k)+k)%n;
}
int main()
{
int t,cs=1;
scanf("%d",&t);
while (t--){
ll ans=0;
scanf("%I64d%I64d%I64d",&n,&m,&k);
printf("Case #%d: ",cs++);
if(k==1)printf("%I64d\n",m);
//f(n,m,k)求得的是编号0~n-1时的编号
else if(m<=1e6)printf("%I64d\n",f(n,m,k)+1);
//变加法为乘法,省略掉后面x个人(自杀直到这一圈的结尾)的一次次加法
//时间复杂度:O(应该能过)
else {
ll cc=n-m+1;
ll ans=(k-1)%cc;
ll num=1;
while(num<m){
//如果下一个自杀的人就是下一圈
if(ans+k>=cc+1){
cc++;
ans=(ans+k)%cc;
num++;
}else {
ll x=(cc-ans-1)/(k-1);
//x --> 当前圈可以 继续自杀多少人
x=min(x,m-num);
ans=ans+x*k;
num+=x;
cc=cc+x;
}
}
printf("%I64d\n",ans+1);
}
}
return 0;
}
//康托展开 && 逆康托展开
static const int FAC[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880}; // 阶乘
int cantor(int *a, int n) {
int x = 0;
for (int i = 0; i < n; ++i) {
int smaller = 0; // 在当前位之后小于其的个数
for (int j = i + 1; j < n; ++j) {
if (a[j] < a[i])
smaller++;
}
x += FAC[n - i - 1] * smaller; // 康托展开累加
}
return x; // 康托展开值
}
void decantor(int x, int n) {
vector <int> v; // 存放当前可选数
vector <int> a; // 所求排列组合
for(int i = 1; i <= n; i++)
v.push_back(i);
for(int i = m; i >= 1; i--) {
int r = x % FAC[i - 1];
int t = x / FAC[i - 1];
x = r;
sort(v.begin(), v.end());// 从小到大排序
a.push_back(v[t]); // 剩余数里第t+1个数为当前位
v.erase(v.begin() + t); // 移除选做当前位的数
}
}
//< 5 > 原根 && 离散对数
//大步小步算法 --> 求解a^x ≡b(mod n) 模数p不为素数
ll ext_log_mod(ll a, ll b, ll n) {
if(b >= n)return -1;//一些特殊情况的判断
a %= n;
if(b == 1)return 0;
//if(n == 1)return -1;
ll cnt = 0;//记录消因子次数
ll tmp = 1;//存当前a'的值
for(ll g = __gcd(a, n); g != 1; g = __gcd(a, n)) {
if(b % g)return -1;//不能整除
b /= g; n /= g;
tmp = tmp * a / g % n;
cnt++;
if(b == tmp)return cnt;
}
ll m = sqrt(n + 0.5);
ll t = b;
map<ll, ll>Map;//记录b * a ^ i, i
Map[b] = 0;
for(int i = 1; i <= m; i++) {
b = b * a % n;
Map[b] = i;
}
a = qpow(a, m, n);
for(int k = 1; k <= m; k++) { //枚举k
tmp = tmp * a % n;//求出tmp*a^(k*m)
if(Map.count(tmp))return k * m - Map[tmp] + cnt;
}
return -1;
}
int tot;//素因子个数
int a[100005];
//质因数分解n
void get_fact(ll n) {
tot = 0;
for(ll i = 2; i * i <= n; i++) {
if(n % i == 0) {
a[tot++] = i;
while(n % i == 0)n /= i;
}
}
if(n != 1)a[tot++] = n;
}
//测试g是不是p的原根 此处p是素数 欧拉函数值为p - 1
bool g_test(ll g, ll p, ll ou) {
for(ll i = 0; i < tot; i++) {
if(pow(g, ou / a[i], p) == 1)return false;
}
return true;
}
//求解p最小原根,本题p为素数//返回最小的原根
int proot(ll p) {
ll ou = euler_phi(p);
get_fact(ou);//素数的欧拉函数值为p - 1
int g = 1;
while(1) {
if(g_test(g, p, ou))return g;
g++;
}
}
//若gcd(a,m)=1,使得a^l = 1(mod m)的最小l值
//直接对euler(m)求出因子即可,从小到大依次判断是不是符合a^d = 1(mod m)
ll ord_mod(ll a, ll m) {
ll ans = 0;
ll ou = euler_phi(m);
for(int i=1; i <= sqrt(ou); i++) {
if(n / i == 0) {
if(qpow(a, i, m) == 1) {
ans = i;
break;
}
if(qpow(a, n/i, m) == 1) {
ans = min(ans, n/i);
}
}
}
}
//< 6 > 线性代数
//矩阵快速幂
const int mod = 1e9+7;
struct pl {
ll a[15][15];
} p,pp;
//矩阵乘法
pl work(pl work,pl y) { //矩阵乘法
pl box;
memset(box.a,0,sizeof(box.a));
for(int i=1; i<=3; i++) {
for(int k=1; k<=3; k++) {
if(work.a[i][k])
for(int j=1; j<=3; j++) {
box.a[i][j]=(box.a[i][j]+(work.a[i][k]*y.a[k][j])%mod)%mod;
}
}
}
return box;
}
//矩阵快速幂
pl fastpow(ll kk) { //快速幂
pl ans;
memset(ans.a,0,sizeof(ans.a));
for(int i=1; i<=3; i++) ans.a[i][i]=1;
while(kk) {
if(kk&1) ans=work(ans,p);
kk>>=1;
p=work(p,p);
}
return ans;
}
//高斯消元法 求 多元一次方程组
const double EPS=1e-8;
#define maxn 105
double A[maxn][maxn]; //x的系数行列式
double B[maxn][maxn+1]; //A + b
double x[maxn]; //ans
double b[maxn]; //方程组等号右侧
int n;
//求解Ax=b,其中A是方阵
void gauss_jordan() {
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
B[i][j] = A[i][j];
}
}
for(int i = 0; i < n; i++) {
B[i][n] = b[i];
}
for(int i = 0; i < n; i++) {
//把正在处理的未知数系数的绝对值最大的式子换到第i行
int pivot = i;
for(int j = i; j < n; j++) {
if(abs(B[j][i] > abs(B[pivot][i]))) pivot = j;
}
for(int j = 0; j <= n; j++) {
swap(B[i][j], B[pivot][j]);
}
//无解或者无穷多解
if(abs(B[i][i]) < EPS) return;
//把正在处理的未知数的系数变成1
for(int j = i + 1; j <= n; j++) {
B[i][j] /= B[i][i];
}
for(int j = 0; j < n; j++) {
if(i != j) {
//从第j个式子中消去第i个未知数
for(int k = i + 1; k <= n; k++) {
B[j][k] -= B[j][i] * B[i][k];
}
}
}
}
for(int i = 0; i < n; i++) {
x[i] = B[i][n];
}
}
//异或 线性基
struct Linear_Basis {
ll b[63],nb[63],tot;
void init() { //初始化
tot=0;
memset(b,0,sizeof(b));
memset(nb,0,sizeof(nb));
}
bool ins(ll x) { //插入数字
for(int i=62; i>=0; i--)
if (x&(1LL<<i)) {
if (!b[i]) {
b[i]=x;
break;
}
x^=b[i];
}
return x>0;
}
ll Max(ll x) { //求最大值
ll res=x;
for(int i=62; i>=0; i--)
res=max(res,res^b[i]);
return res;
}
ll Min(ll x) { //求最小值
ll res=x;
for(int i=0; i<=62; i++)
if (b[i]) res^=b[i];
return res;
}
void rebuild() { //将线性基改造成每一位相互独立
for(int i=62; i>=0; i--)
for(int j=i-1; j>=0; j--)
if (b[i]&(1LL<<j)) b[i]^=b[j];
for(int i=0; i<=62; i++)
if (b[i]) nb[tot++]=b[i];
}
ll Kth_Max(ll k) { //第k大值
ll res=0;
for(int i=62; i>=0; i--)
if (k&(1LL<<i)) res^=nb[i];
return res;
}
} LB;
L_B merge(const L_B &n1,const L_B &n2) { //线性基合并
L_B ret = n1;
for (int i = 60; i >= 0; i--)
if (n2.d[i])
ret.insert(n1.d[i]);
return ret;
}
转载:https://blog.csdn.net/qq_42323600/article/details/102565470
查看评论