原题解链接:https://ac.nowcoder.com/discuss/181037

此题为送温暖题目。。

把所有的数字转换为三进制,对于每个卡片都是形如00000100000000010000的形式

所以SS222222222222的形式,共有nn

然后考虑当第ii位上为11的时候,表示这一位上需要选113i3^i 的卡片,同样,为22时需要22个,为00时只需一个。

当需要11个时,有两种选择,其他的都只有一种选择。

又因为SS的形式是222222222222

我们从11枚举到SS,只需考虑哪些位置上面是22即可。

如果当前有ii个位置为11那么共有CniC_n^i 种情况,且贡献为2i2^i ,然后其他位置可以为00,也可以为22。所以贡献为2ni2^{n-i} 。所以当前的贡献就是Cni×2i×2ni=Cni×2nC_n^i \times 2^i \times 2^{n-i} = C_n^i \times 2^n

所以最终答案为i=0nCni×2n\sum\limits_{i=0}^nC_n^i \times 2^n

2n2^n 提出来。那就是2n×i=0nCni2^n \times \sum\limits_{i=0}^nC_n^i

用二项式定理合并那个\sum,其实就是2n2^n ,所以最终答案为4n4^n

注意到当i=0i=0时是不符合题目要求的,所以要减去他的贡献11

所以真正的最后答案是4n14^n-1


#include <stdio.h>
#include <cstring>
#include <cstdlib>
#include <cassert>
typedef long long ll;
char s[100100];
ll Mul(ll a, ll b, ll m){
	ll rnt = 0;
	a %= m;
	while(b){
		if(b & 1) rnt = (rnt + a) % m;
		a = (a << 1) % m;
		b >>= 1;
	}
	return rnt;
}
ll Pow(ll a, ll n, ll m){
    if(n == 1) return a;
	else{
		ll rnt = Pow(a, n / 2, m);
		rnt = Mul(rnt, rnt, m);
		if(n & 1) rnt = Mul(a, rnt, m);
		return rnt;
	}
	return 0;
}
int main(){
	int T; scanf("%d", &T);
	while(T--){
		ll m;
		scanf("%s%lld", s, &m);
		ll phi = m, t = m;
		for(ll i = 2; i <= t / i; ++i)
			if(t % i == 0){
				phi = phi / i * (i - 1);
				while(t % i == 0) t /= i;
			}
		if(t > 1)
			phi = phi / t * (t - 1);
		ll res = 0; bool flag = false;
		for(int i = 0; s[i]; ++i){
			res = res * 10 + s[i] - '0';
			if(res >= phi) res %= phi, flag = true;
		}
		ll ans = (Pow(4 % m, res + flag * phi, m) - 1 + m) % m;
		printf("%lld\n", ans);
	}
	return 0;
}