题目大意
找到满足 $s_1\operatorname{and}s_2=s$ 的字符串对 $(s_1,s_2)$ 的数量,且 $s_1$ 和 $s_2$ 的长度都要与 $s$ 相同,并给出了字符转为数字,进行比较的规则。
解题思路
由于字符串 $s_1$ 和 $s_2$ 的每一位进行与运算的结果都对应着 $s$ 的相应位置,因此我们可以对 $s$ 的每一位进行单独分析。
针对 $s$ 的每一位,只有两种情况:
- 该位二进制为 $1$,则 $s_1$ 和 $s_2$ 的对应位都为 $1$。
- 该位二进制为 $0$,则 $s_1$ 和 $s_2$ 的对应位为 $00$,$01$ 或 $10$。
因此,对于 $s$ 的每一位,我们只需要统计该位表示为数字后,二进制表示中 $0$ 的个数总和,记为 $sum$,对于每一个 $0$ 最多有三种情况,根据乘法原理,最终答案为 $3^{sum}$。
代码
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#define int long long
#define endl "\n"
using namespace __gnu_cxx;
using namespace __gnu_pbds;
using namespace std;
const int MOD=1e9+7;//记得模1e9+7
int ans;
inline int check(int n)//检查函数,计算二进制表示下 0 的的个数
{
int sum=0;
for(int i=1;i<=6;i++)//数最大为 64,则二进制最多有 6 位,只需检查 6 位
{
if(n&1)n>>=1;//当前末尾为 1,右移一位
else n>>=1,sum++;//末尾为 0,计数器加 1,右移一位
}
return sum;
}
inline int fastpow(int b,int a)//此题需要用到快速幂
{
int res=1;
while(b)
{
if(b&1) res=res*a%MOD;
a=a*a%MOD;
b>>=1;
}
return res;
}
signed main()
{
string s;
cin>>s;
for(char c:s)
{
int n;
if(c>='0'&&c<='9')n=c-'0';//按题目要求进行字符与数字间转换
if(c>='A'&&c<='Z')n=c-'A'+10;
if(c>='a'&&c<='z')n=c-'a'+36;
if(c=='-')n=62;
if(c=='_')n=63;
ans+=check(n);//累加 0 的个数
}
cout<<fastpow(ans,3);
return 0;
}
时间复杂度
$O(|s|\log |s|)$,其中 $|s|$ 表示字符串 $s$ 的长度。
空间复杂度
$O(|s|)$,所需存储空间取决于字符串 $s$ 的长度,并随着 $s$ 长度的增加而线性增加。