模运算
POJ 1150: The Last Non-zero Digit
题解链接 https://blog.csdn.net/Avalon_cc/article/details/79967855
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
题解链接 https://blog.csdn.net/Avalon_cc/article/details/79967855
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#include<bitset>
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=+5;
const int INF=0x3f3f3f3f;
const int mod=10;
int get2(int n){ //n!中因子2的个数
if(n==0) return 0;
return get2(n/2)+n/2;
}
int get5(int n){ //n!中因子5的个数
if(n==0) return 0;
return get5(n/5)+n/5;
}
int g(int n,int x){ //1~n中除去5的奇倍数后,奇数数列末尾为x的数的个数
if(n==0) return 0;
return n/10+(n%10>=x)+g(n/5,x);
}
int getx(int n,int x){ //1~n中除去5的奇倍数后,全数列末尾为x的数的个数
if(n==0) return 0;
return getx(n/2,x)+g(n,x);
}
int table[4][4]={
{6,2,4,8}, //2^n%10的循环节,注意如果2的个数为0时候,结果应该是1,要特殊处理。
{1,3,9,7}, //3
{1,7,9,3}, //7
{1,9,1,9} //9
};//3,7,9的循环节中第一位,刚好是1,故不需要考虑这些数字出现次数为0的情况。
int main() {
// ios::sync_with_stdio(false);
//freopen("The Last Non-zero Digit.in","r",stdin);
int n,m;
// D(get2(20));D(get5(20));D(g(20,3));D(getx(20,3));E;
while(cin>>n>>m){
int num2=get2(n)-get2(n-m);
int num5=get5(n)-get5(n-m);
int num3=getx(n,3)-getx(n-m,3);
int num7=getx(n,7)-getx(n-m,7);
int num9=getx(n,9)-getx(n-m,9);
if(num5>num2){
cout<<5<<endl;
continue;
}
int ans=1;
if(num5!=num2){
ans*=table[0][(num2-num5)%4];
ans%=mod;
}
ans=(ans*table[1][num3%4]%mod*table[2][num7%4]%mod*table[3][num9%4]%mod)%mod;
cout<<ans<<endl;
}
return 0;
}
#endif
#ifdef method_2
/*
*/
#endif
#ifdef method_3
/*
*/
#endif
POJ 1284: Primitive Roots
求原根个数的模板题。
定理:如果p有原根,则它恰有φ(φ(p))个不同的原根(无论p是否为素数都适用)
p为素数,当然φ(p)=p-1,因此就有φ(p-1)个原根。
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
求原根个数的模板题。
定理:如果p有原根,则它恰有φ(φ(p))个不同的原根(无论p是否为素数都适用)
p为素数,当然φ(p)=p-1,因此就有φ(p-1)个原根。
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=+5;
const int INF=0x3f3f3f3f;
int phi(int n){
int ans=n;
// for(int i=2;i<=sqrt(n);i++){ //这样用sqrt,poj会CE
for(int i=2;i<=(int)sqrt((double)n);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;
}
int main() {
ios::sync_with_stdio(false);
//freopen("Primitive Roots.in","r",stdin);
int p;
while(scanf("%d",&p)!=EOF){
printf("%d\n",phi(p-1));
}
return 0;
}
#endif
#ifdef method_2
/*
*/
#endif
#ifdef method_3
/*
*/
#endif
POJ 2115: C Looooops
可以求,同时x和y的值就是的一组解。
对于该题,相当于求关于x的同余方程的最小整数解。
对上式变形得,。即。
设。根据裴蜀定理,若(B-A)%d==0,则原方程有整数解。
于是先特判是否有解后,在方程两遍同除以d(模数也要除以d)。
最后将exgcd算出的x乘以然后再对求模即可。
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
d=exgcd(a,b,x,y)可以求gcd(a,b)=d,同时x和y的值就是ax+by=1的一组解。
对于该题,相当于求关于x的同余方程A+xC≡B(mod 2^k)的最小整数解。
对上式变形得,A+xC=B-y*2^k。即xC+y*2^k=B-A。
设d=gcd(C,2^k)。根据裴蜀定理,若(B-A)%d==0,则原方程有整数解。
于是先特判是否有解后,在方程两遍同除以d(模数也要除以d)。
最后将exgcd算出的x乘以(B-A)/d然后再对2^k/d求模即可。
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=+5;
const int INF=0x3f3f3f3f;
ll A,B,C,k;
ll exgcd(ll a,ll b,ll& x,ll& y){
if(!b){
x=1,y=0;
return a;
}
ll d=exgcd(b,a%b,x,y);
ll temp=x;
x=y;
y=temp-a/b*y;
return d;
}
int main() {
// ios::sync_with_stdio(false);
// freopen("C Looooops.in","r",stdin);
while(scanf("%lld%lld%lld%lld",&A,&B,&C,&k)!=EOF){
if(!A&&!B&&!C&&!k) break;
ll x,y;
ll d=exgcd(C,(1ll<<k),x,y);
// D(d);D(x);D(y);E;
if((B-A)%d){
printf("FOREVER\n");
}
else{
ll mod=(1ll<<k)/d;
ll ans=(x*(B-A)/d%mod+mod)%mod;
printf("%lld\n",ans);
}
}
return 0;
}
#endif
#ifdef method_2
/*
*/
#endif
#ifdef method_3
/*
*/
#endif
POJ 3708: Recurrent Function
题解链接 http://www.hankcs.com/program/algorithm/poj-3708-recurrent-function.html
模数和底数不一定互质,所以需要应用多次欧几里得算法。
除此之外,还需要高精度,不想打。
代码如下
POJ 2720: Last Digits
题解链接 https://blog.csdn.net/yuege38/article/details/78989456
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
题解链接 https://blog.csdn.net/yuege38/article/details/78989456
http://ww3.sinaimg.cn/large/6cbb8645jw1es7p9f2l68j20fm03hdfx.jpg
*/
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#include<iomanip>
#define int long long
#define re register
using namespace std;
typedef long long ll;
const int maxn=100+5;
int base[10]= {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000};
int tab[maxn][maxn]; //tab[i,j]表示i^i^i...^i(j个i)是否>1e7,是则为-1,否则为i^i^i...^i(j个i)的确切值/上次计算过的答案(用于开始时的判断)
int fxb[maxn][maxn]; //fxb[i,j]表示i^i^i...^i(j个i)是否>1e7,否则为i^i^i...^i(j个i)的确切值(用于欧拉定理时的递归计算时的判断)
inline int limit_power(int a,int b) {
ll res=1;
for(int i=1; i<=b; ++i) {
res=res*1ll*a;
if(res>1e7) return -1;
}
return res;
}
void init() {
memset(tab,-1,sizeof(tab));
memset(fxb,-1,sizeof(fxb));
for(int i=1; i<=maxn-5; ++i) {
tab[i][0]=fxb[i][0]=1;
for(int j=1; j<=maxn-5; ++j) {
tab[i][j]=fxb[i][j]=limit_power(i,fxb[i][j-1]);
if(tab[i][j]==-1) break;
}
}
}
inline ll ksm(int x,int b,int mod) {
ll res=1;
while(b) {
if(b&1) res=res*x%mod;
x=x*x%mod;
b>>=1;
}
return res;
}
inline int get_phi(int x) {
int ans=x;
for(int i=2; i*i<=x; ++i) {
if(x%i==0) {
ans=ans/i*(i-1);
while(x%i==0) x/=i;
}
}
if(x>1) ans=ans/x*(x-1);
return ans;
}
/*
int solve(int b,int a,int mod) {
if(fxb[b][a]!=-1) return fxb[b][a]%mod;//
int phi=get_phi(mod);
if(fxb[b][a-1]!=-1&&fxb[b][a-1]<=phi) return ksm(b,fxb[b][a-1],mod);
return ksm(b,solve(b,a-1,phi)+phi,mod);
}
*/
int solve(int b,int x,int mod) {
if(fxb[b][x]==-1) {
int phi=get_phi(mod);
if(fxb[b][x-1]!=-1&&fxb[b][x-1]<phi) {
return ksm(b,fxb[b][x-1],mod);
} else {
return ksm(b,solve(b,x-1,phi)+phi,mod);
}
} else {
return tab[b][x]%mod;
}
}
signed main() {
// ios::sync_with_stdio(false);
//freopen("Last Digits.in","r",stdin);
ll b,x,n;
init();
while(scanf("%lld",&b)!=EOF) {
if(!b) break;
scanf("%lld%lld",&x,&n);
int res;
if(tab[b][x]!=-1) { //不需要降幂计算
res=tab[b][x]%base[n];
} else {
tab[b][x]=solve(b,x,1e7); //用欧拉函数降幂 开始递归(由于有多组样例 所以用tab记录下来)
res=tab[b][x]%base[n];
}
cout<<setfill('0')<<setw(n)<<res<<endl;
}
return 0;
}
#endif
矩阵
代码如下
/*
题意:有n个窗口,有n个师傅,每个师傅可以管理很多窗口,可以重复的,给一个师傅下命令,
这个师傅会管理他所有的窗口,如果是关闭的就打开,如果是打开的就关闭,现在想让所有的窗口打开,问你怎么下命令。
思路:将每个师傅管理的窗口转化成01序列,末尾加0,表示方程的结果,然后凑成矩阵,高斯消元解方程,消元的时候变成异或。
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#include<bitset>
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=250+5;
const int INF=0x3f3f3f3f;
int n;
int a[maxn][maxn];//增广矩阵
int x[maxn];//解集
void init(){
memset(a,0,sizeof(a));
memset(x,0,sizeof(x));
}
void Gauss(){
for(int i=1;i<=n;i++){
int col=-1;
for(int j=i;j<=n;j++){//找到第一个不为零的行
if(a[j][i]){
col=j;
break;
}
}
for(int j=i;j<=n+1;j++){
swap(a[i][j],a[col][j]);
}
for(int j=i+1;j<=n;j++){
if(a[j][i]!=0){
for(int k=i;k<=n+1;k++){
a[j][k]^= a[i][k];
}
}
}
}
for (int i=n;i>=1;--i){
x[i] = a[i][n+1];
for (int j=i-1;j>=1;--j){
a[j][n+1]^=(x[i]&a[j][i]);
}
}
}
int main() {
// ios::sync_with_stdio(false);
//freopen("Central heating.in","r",stdin);
init();
scanf("%d",&n);
for(int i=1;i<=n;i++){
int num;
while(scanf("%d",&num)){
if(num==-1) break;
// D(num);D(i);E;
a[num][i]=1;
}
a[i][n+1]=1;
}
/*
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
printf("%d ",a[i][j]);
}
printf("\n");
}
*/
Gauss();
/*
for(int i=1;i<=n;i++){
D(x[i]);
for(int j=1;j<=n;j++){
printf("%d ",a[i][j]);
}
printf("\n");
}
*/
for(int i=1;i<=n;i++) if(x[i]) printf("%d ",i);
return 0;
}
POJ 3532: Resistance
在电路中,很难直接根据输入判断每条导线中电流的流向。
因此需要基尔霍夫定律来列出每个点电位的方程。
具体题解链接
https://blog.csdn.net/yuege38/article/details/78946445
http://m.bubuko.com/infodetail-1987259.html
代码如下
/*
在电路中,很难直接根据输入判断每条导线中电流的流向。
因此需要基尔霍夫定律来列出每个点电位的方程。
具体题解链接
https://blog.csdn.net/yuege38/article/details/78946445
http://m.bubuko.com/infodetail-1987259.html
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#include<bitset>
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=100+5;
const int INF=0x3f3f3f3f;
const double eps=1e-4;
int n,m;
double a[maxn][maxn],x[maxn];// a和x分别为方程的左边的矩阵和等式右边的值,求解之后x存的就是结果
int equ,var;// 方程数和未知数个数
int Gauss() {// 返回0表示无解,1表示有解
int i,j,k,col,max_r;
for(k=1,col=1; k<=equ&&col<=var; k++,col++) {
max_r=k;
for(i=k+1; i<=equ; i++)if(fabs(a[i][col])>fabs(a[max_r][col]))max_r=i;
if(fabs(a[max_r][col])<eps)return 0;
if(k!=max_r) {
for(j=col; j<=var; j++)swap(a[k][j],a[max_r][j]);
swap(x[k],x[max_r]);
}
x[k]/=a[k][col];
for(j=col+1; j<=var; j++)a[k][j]/=a[k][col];
a[k][col]=1;
for(i=0; i<=equ; i++)if(i!=k) {
x[i]-=x[k]*a[i][k];
for(j=col+1; j<=var; j++)a[i][j]-=a[k][j]*a[i][col];
a[i][col]=0;
}
}
return 1;
}
int main() {
// ios::sync_with_stdio(false);
//freopen("Resistance.in","r",stdin);
scanf("%d%d",&n,&m);
int from,to;
double r;
for(int i=1; i<=m; i++) {
scanf("%d%d%lf",&from,&to,&r);
//对于电路中的一条from到to,阻值为r的边。方程组中会有四个项的系数受到影响。
a[from][from]+=1.0/r,a[to][to]+=1.0/r,a[from][to]-=1.0/r,a[to][from]-=1.0/r;
}
// a[n][n]+=1.0;
x[1]=1.0,x[n]=-1.0;
/*
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
printf("%.2f ",a[i][j]);
}
E;
}
*/
equ=var=n;
Gauss();
printf("%.2lf ",x[1]-x[n]); //事实上 x[n]等于0恒成立
// for(int i=1; i<=n; i++) printf("%.2lf ",x[i]);
return 0;
}
POJ 3526: The Teacher’s Side of Math
根据每个无理项的系数和为0(最高项系数和为1)来列方程求解。
题解链接 https://blog.csdn.net/FSAHFGSADHSAKNDAS/article/details/89089005
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
根据每个无理项a^{x/m}b^{y/n}的系数和为0(最高项系数和为1)来列方程求解。
题解链接 https://blog.csdn.net/FSAHFGSADHSAKNDAS/article/details/89089005
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#include<bitset>
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=20+5+5;
const int INF=0x3f3f3f3f;
ll a,m,b,n,C[maxn][maxn];
double G[maxn][maxn];
void getc (int n) {
for (int i = 0; i <= n; i++) {
C[i][0] = C[i][i] = 1;
for (int j = 1; j < i; j++)
C[i][j] = C[i-1][j-1] + C[i-1][j];
}
}
void init(){
memset(G,0,sizeof(G));
int N=n*m;
for(int i=0;i<=N;i++){
for(int j=0;j<=i;j++){
int l=j,r=i-j;
double temp=C[i][l]*pow(a*1.0,(double)l/m)*pow(b*1.0,(double)r/n);
// D(temp);E;
l%=m,r%=n;
G[l*n+r][i]+=temp;
}
}
G[N][N]=1; //a_nm
G[N][N+1]=1; //最高项系数和为1
}
void Gauss (int n) {
/*
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= n; j++)
printf("%lf ", G[i][j]);
printf("\n");
}
*/
for (int i = 0; i < n; i++) {
int r = i;
for (int j = i + 1; j < n; j++)
if (fabs(G[j][i]) > fabs(G[r][i]))
r = j;
if (r != i) {
for (int j = 0; j <= n; j++)
swap(G[r][j], G[i][j]);
}
if (fabs(G[i][i]) < 1e-9)
continue;
for (int k = i + 1; k < n; k++) {
double f = G[k][i] / G[i][i];
for (int j = 0; j <= n; j++)
G[k][j] -= G[i][j] * f;
}
}
for (int i = n-1; i >= 0; i--) {
for (int j = i+1; j < n; j++)
G[i][n] -= G[j][j] * G[i][j];
G[i][i] = G[i][n] / G[i][i];
if (fabs(G[i][i]) < 1e-9)
G[i][i] = 0;
}
printf("%.0f", G[n-1][n-1]);
for (int i = n-2; i >= 0; i--)
printf(" %.0f", G[i][i]);
printf("\n");
}
int main() {
// ios::sync_with_stdio(false);
// freopen("The Teacher’s Side of Math.in","r",stdin);
getc(maxn-5);
while(scanf("%lld%lld%lld%lld",&a,&m,&b,&n)!=EOF){
if(!a&&!b&&!m&&!n) break;
init();
Gauss(n*m+1);
}
return 0;
}
#endif
#ifdef method_2
/*
*/
#endif
#ifdef method_3
/*
*/
#endif
计数
POJ 2407: Relatives
欧拉函数裸题,不再赘述。
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
欧拉函数裸题,不再赘述。
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#include<bitset>
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=1000000000+5;
const int INF=0x3f3f3f3f;
int phi(int n){
int res=n;
for(int i=2;i<=(int)sqrt((double)n);i++){
if(n%i==0){
res=res/i*(i-1);
while(n%i==0) n/=i;
}
}
if(n>1) res=res/n*(n-1);
return res;
}
int main() {
// ios::sync_with_stdio(false);
//freopen("Relatives.in","r",stdin);
int n;
while(cin>>n){
if(!n) break;
cout<<phi(n)<<endl;
}
return 0;
}
#endif
#ifdef method_2
/*
*/
#endif
#ifdef method_3
/*
*/
#endif
POJ 1286: Necklace of Beads
与POJ2049相仿,不再赘述。
注意考虑s=0的情况,需要输出0,直接跑会RE。
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
与POJ2049相仿,不再赘述。
注意考虑s=0的情况,需要输出0,直接跑会RE。
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#include<bitset>
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=32+5;
const int INF=0x3f3f3f3f;
int c=3,s;
ll ans;
void init(){
ans=0ll;
}
int gcd(int a,int b){
return !b?a:gcd(b,a%b);
}
ll ksm(ll a,ll b){
ll res=1ll;
while(b){
if(b&1) res=res*a;
a=a*a;
b>>=1;
}
return res;
}
void solve(){
init();
for(int i=0;i<=s-1;i++){ //旋转 每种情况被重复算了n次
ll d=(ll)gcd(i,s);
ll res=ksm((ll)c,d);
// D(c);D(d);D(res);E;
ans+=res;
}
//翻转 每种情况被重复计算了n次
if(s&1) ans+=(ll)s*ksm((ll)c,(ll)s/2+1);
//s为奇数 对称轴穿过一个顶点和一条边,顶点选法有s种,剩余每对点颜色一样
//因此穿过对称轴的点颜色有c种,剩余s/2对点,选法有c^(s/2)种
else ans+=(ll)s/2*ksm((ll)c,(ll)s/2)+(ll)s/2*ksm((ll)c,(ll)s/2+1);
//s为偶数 分两种情况
//1 对称轴穿过两条边,边的选法有s/2种,顶点颜色选法c^(s/2)种
//2 对称轴穿过两个点,点的选法有s/2种,顶点颜色选法c^(s/2-1+2)种(+2是作为对称轴的两个顶点)
cout<<ans/(2*s)<<endl; //总体上 每种情况被重复算了2n次
}
int main() {
// ios::sync_with_stdio(false);
//freopen("Necklace of Beads.in","r",stdin);
while(cin>>s){
if(s==-1) break;
if(s==0){
cout<<0<<endl;
continue;
}
solve();
}
return 0;
}
#endif
#ifdef method_2
/*
*/
#endif
#ifdef method_3
/*
*/
#endif
POJ 2409: Let it Bead
书上原题,需要额外考虑翻转的情况。
题解链接 http://hzwer.com/6861.html
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
书上原题,需要额外考虑翻转的情况。
题解链接 http://hzwer.com/6861.html
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#include<bitset>
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=32+5;
const int INF=0x3f3f3f3f;
int c,s;
ll ans;
void init(){
ans=0ll;
}
int gcd(int a,int b){
return !b?a:gcd(b,a%b);
}
ll ksm(ll a,ll b){
ll res=1ll;
while(b){
if(b&1) res=res*a;
a=a*a;
b>>=1;
}
return res;
}
void solve(){
init();
for(int i=0;i<=s-1;i++){ //旋转 每种情况被重复算了n次
ll d=(ll)gcd(i,s);
ll res=ksm((ll)c,d);
// D(c);D(d);D(res);E;
ans+=res;
}
//翻转 每种情况被重复计算了n次
if(s&1) ans+=(ll)s*ksm((ll)c,(ll)s/2+1);
//s为奇数 对称轴穿过一个顶点和一条边,顶点选法有s种,剩余每对点颜色一样
//因此穿过对称轴的点颜色有c种,剩余s/2对点,选法有c^(s/2)种
else ans+=(ll)s/2*ksm((ll)c,(ll)s/2)+(ll)s/2*ksm((ll)c,(ll)s/2+1);
//s为偶数 分两种情况
//1 对称轴穿过两条边,边的选法有s/2种,顶点颜色选法c^(s/2)种
//2 对称轴穿过两个点,点的选法有s/2种,顶点颜色选法c^(s/2-1+2)种(+2是作为对称轴的两个顶点)
cout<<ans/(2*s)<<endl; //总体上 每种情况被重复算了2n次
}
int main() {
// ios::sync_with_stdio(false);
//freopen("Let it Bead.in","r",stdin);
while(cin>>c>>s){
if(!c&&!s) break;
solve();
}
return 0;
}
#endif
#ifdef method_2
/*
*/
#endif
#ifdef method_3
/*
*/
#endif
网友评论