Codeforces Round #355 (Div. 2)

C. Vanya and Label

法一、直白预处理 https://blog.csdn.net/qq_32473657/article/details/51567689

#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\n",ans);
}
View Code

法二、快速幂衍生

#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;
}
View Code

快速幂

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;
}
View Code

法三、>>运算

#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\n", ans);

    return 0;
}
View Code

<<运算符百科

该运算符为双目运算符,作用是把一个整型数所有位向左移动指定位数,移动到左边界外的多余二进制位丢弃,从右边界移入0。左移运算两个操作数为整数类型。第一个操作数是进行移位操作的数,第二个操作数指定第一个操作数移动位数。如果第二个操作数等于0则不发生任何移位。

应用举例:
一,问:计算表达式14 << 2的值。
答:表达式14 << 2的值为56,因为14(即二进制的00001110)向左移两位等于56(即二进制的00111000)。
二,问: 计算表达式8 >> 2的值。
答:表达式8 >> 2的值为2,因为8(即二进制的00001000)向右移两位等于2(即二进制的00000010)。

 

posted @ 2018-08-25 09:11  LLbinGG  阅读(187)  评论(0编辑  收藏  举报