zoukankan      html  css  js  c++  java
  • NowCoder2018多校A Ternary String 拓展欧拉定理

    NowCoder2018多校A Ternary String 拓展欧拉定理

    题意

    给定带前导0的三进制数,每秒自动进行一次操作,1的后面多一个0,2的后面多一个1,开头的字符被删除,求这个数变为空的操作次数

    求操作次数取模(1e9+7)

    [1 leq |s| leq 10^5 ]

    分析

    考虑记录时间,原串中每个数带来的贡献,可以简单归纳得出

    0:(t + 1)

    1:(2(t + 1))

    2:(3(2^{t + 1} - 1))

    操作12都可以轻松得到结果,对于3,计算(2^{t + 1} mod MOD)是不方便的,考虑使用拓展欧拉定理

    [a^b equiv egin{cases} a^{b mod varphi(m)},gcd(a,m) = 1\ a^b ,gcd(a,m) eq 1,b leq varphi(m) (mod m)\ a^{b mod varphi(m) +varphi(m)},gcd(a,m) eq 1,b geq varphi(m) end{cases} ]

    使用时,要求幂对(varphi(m))取模,因此我们记录(t)时还需额外记录(varphi(m))意义下的(t),维护(varphi(m)) 意义下的(t)又需要嵌套上模(varphi(varphi(m)))

    为了方便实现,可以采用DFS的方式记录当前第几个数和当前的模数,至于为什么不用判断(b geq varphi(m)),我也不是很懂

    代码

    const int MOD = (int)1e9 + 7;
    
    int m[35],ans[35];
    
    
    inline int mul(int a,int b,int i){
        return (ll)a * b % i;
    }
    
    
    inline  void add(int &a,int b,int i){
        a += b;
        if(a >= i) a -= i;
    }
    
    inline int ksm(int a,ll b = MOD - 2,int m = MOD){
        int ans = 1;
        int base = a;
        while(b){
            if(b & 1) {
                ans = (ll)ans * base % m;
            }
            base = (ll)base * base % m;
            b >>= 1;
        }
        return ans;
    }
    
    
    inline int get_phi(int n) {
        int m = int(sqrt(n + 0.5));
        int ans = n;
        for (int i = 2; i <= m; i++) {
            if (n % i == 0) {
                ans = ans / i * (i - 1);
                while (n % i == 0) n /= i;
            }
        }
        if (n > 1) ans = ans / n * (n - 1);
        return ans;
    }
    
    unordered_map<int,int> mp;
    char s[100005];
    
    int dfs(int len,int m){
        if(!len) return 0;
        if(s[len] == '0')
            return (dfs(len - 1,m) + 1) % m;
        if(s[len] == '1') 
            return (ll)2 * (dfs(len - 1,m) + 1) % m;
        //if(mp[m] != 1) return (mul(3,ksm(2,(dfs(len - 1,mp[m]) + 1) % mp[m],m),m) + m - 3) % m;
        int p = dfs(len - 1,mp[m]) + 1;
        if(m != 1 && m != MOD) {
            if(p >= mp[m]) return (mul(3,ksm(2,p % mp[m] + mp[m],m),m) + m - 3) % m;
            else return (mul(3,ksm(2,p % mp[m],m),m) + m - 3) % m;
        }  
        return (mul(3,ksm(2,p % mp[m],m),m) + m - 3) % m;
    }
    
    int main(){
        int T = rd();
        int tmp = MOD;
        mp[1] = 1;
        while(tmp > 1) {
            mp[tmp] = get_phi(tmp);
            tmp = mp[tmp];
        }
        while(T--){
           scanf("%s",s + 1);
           int len = strlen(s + 1);
           printf("%d
    ",dfs(len,MOD));
        }
    }
    
  • 相关阅读:
    VMWare虚拟机15.X局域网网络配置(修改网卡)
    Redis的中并发问题的解决方案小结
    搭建一个dubbo+zookeeper平台
    react与redux学习资料的整理
    如何利用python+Selenium对登录的验证码进行验证?
    (基础篇)哪些面试遇见的坑——面试必看基础题
    测试员小白必经之路----常见的linux操作命令
    测试员小白必经之路----常见的Dos命令
    Elastcisearch.Nest 7.x 系列`伪`官方翻译:通过 NEST 来快捷使用 Elasticsearch
    StackExchange.Redis 系列 1:基础使用
  • 原文地址:https://www.cnblogs.com/hznumqf/p/15369391.html
Copyright © 2011-2022 走看看