C. Vanya and Label
法一、直白预处理 https://blog.csdn.net/qq_32473657/article/details/51567689
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<stdio.h> #include<string.h> using namespace std; const int MOD=1e9+7; char s[100005]; int sum[65]; int change(char c) { if(c>='0'&&c<='9')return c-'0'; else if(c>='A'&&c<='Z')return c-'A'+10; else if(c>='a'&&c<='z')return c-'a'+36; else if(c=='-')return 62; else if(c=='_')return 63; } int main() { for(int i=0;i<64;i++) //情况数打表预处理 { for(int j=0;j<64;j++) { sum[i&j]++; } } long long ans=1; scanf("%s",s); for(int i=0;i<strlen(s);i++) { ans=((ans*sum[change(s[i])]))%MOD; } printf("%d ",ans); }
法二、快速幂衍生
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <algorithm> #include <stdio.h> #include <string> #include <string.h> #include <map> using namespace std; #define ll long long const ll inf=1e9+7; char ss[]={"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_"}; string s; map<char,ll>mp; int main() { int m=strlen(ss); for(int i=0;i<m;i++) mp.insert(make_pair(ss[i],i)); cin>>s; int n=s.length(); ll ans=1; for(int i=0;i<n;i++) { ll temp=1; ll x=mp[s[i]]; int f=0; while(x) //快速幂衍生 { f++; if(!(x&1)) temp=(temp%inf*3)%inf; x>>=1; } f=6-f; while(f--) temp=(temp%inf*3)%inf; ans=ans*temp%inf; } cout<<ans<<endl; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
int poww(int a,int b){ int ans=1,base=a; while(b!=0){ if(b&1!=0) ans*=base; base*=base; b>>=1; } return ans; }
法三、>>运算
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cstdlib> #include <string> #include <cstring> using namespace std; typedef long long ll; const ll MOD = (ll)1e9 + 7; const int N = 100100; ll ans = 1; char s[N]; int getNum(char c) { if ('0' <= c && c <= '9') return c - '0'; if ('A' <= c && c <= 'Z') return 10 + c - 'A'; if ('a' <= c && c <= 'z') return 36 + c - 'a'; if (c == '-') return 62; if (c == '_') return 63; throw; } int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); scanf("%s", s); int n = strlen(s); for (int i = 0; i < n; i++) { int x = getNum(s[i]); for (int k = 0; k < 6; k++) if (((x >> k) & 1) == 0) // >>运算符,右移操作 ans = (ans * 3) % MOD; } printf("%lld ", ans); return 0; }
该运算符为双目运算符,作用是把一个整型数所有位向左移动指定位数,移动到左边界外的多余二进制位丢弃,从右边界移入0。左移运算两个操作数为整数类型。第一个操作数是进行移位操作的数,第二个操作数指定第一个操作数移动位数。如果第二个操作数等于0则不发生任何移位。
应用举例:
一,问:计算表达式14 << 2的值。
答:表达式14 << 2的值为56,因为14(即二进制的00001110)向左移两位等于56(即二进制的00111000)。
二,问: 计算表达式8 >> 2的值。
答:表达式8 >> 2的值为2,因为8(即二进制的00001000)向右移两位等于2(即二进制的00000010)。