牛客网多校训练4 A Ternary String(高阶幂次取模)

题意:每一次都在2后面插一个1,在1后面插一个0,然后删除第一个数,问你这个字符串什么时候消失

思路:这个题是假的-1,队友发现一个0的贡献是1s,一个1是2s,一个2是6*2^3+3,这样我们就可以算出整个串的值,但是这里还有一个取模的问题,其实就是扩展欧拉定理,你对一个数的幂数取模,要模上模数的欧拉函数值,所以这里需要一直迭代,其实1e9+7的欧拉拉函数迭代28次就变成1了,这里有个地方就是看了聚聚们的代码,发现有人是用递归写的,很方便,就抄袭了一份(QAQ),比赛的时候差一点点,提交一直wa,后来想到是因为需要一直求欧拉的欧拉,而且想到的时候也没时间改了,凉凉

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL MOD=1e9+7;
const int maxn=100100;
char s[maxn];
map<LL,LL>mp;
 
//直接求解欧拉函数
LL euler(LL n){ //返回e(n)
     LL res=n,a=n;
     for(LL i=2;i*i<=a;i++){
         if(a%i==0){
             res=res/i*(i-1);//先进行除法是为了防止中间数据的溢出
             while(a%i==0) a/=i;
         }
     }
     if(a>1) res=res/a*(a-1);
     return res;
}
 
LL qmod(LL a,LL b,LL p)
{
    if (b == 0) return 1;
    LL r = a % p;
    LL k = 1;
    while (b > 1){
        if ((b & 1)!=0)
            k = (k * r) % p;
        r = (r * r) % p;
        b >>= 1;
    }
    return (r * k) % p;
}
 
LL solve(int i,LL p){
//    printf("test %d %lld\n",i,p);
    if (i==-1) return 0;
    if (p==1) return 0;
    if (s[i]=='2') return (3*qmod(2,solve(i-1,mp[p])+1,p)-3+p)%p;
    if (s[i]=='1') return ((solve(i-1,p)+1)*2+p)%p;
    if (s[i]=='0') return (solve(i-1,p)+1+p)%p;
    return 0;
}
void init()
{
    LL asd=1e9+7;
    while(asd!=1){
        mp[asd]=euler(asd);
        asd=mp[asd];
    }
    mp[asd]=1;
}
int main()
{
    int T;
    init();
    scanf("%d",&T);
    while(T--){
        scanf("%s",s);
        int len=strlen(s);
        printf("%lld\n",solve(len-1,MOD)%MOD);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/lalalatianlalu/p/9383081.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值