zoukankan      html  css  js  c++  java
  • hdu 6021 MG loves string (一道容斥原理神题)(转)

    MG loves string
     
     Accepts: 30    Submissions: 67
     Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
    问题描述
    MGMG是一个很忙碌的男孩子。今天他沉迷于这样一个问题:

    对于一个长度为NN的由小写英文字母构成的随机字符串,当它进行一次变换,所有字符ii都会变成a[i]a[i]。

    MGMG规定所有a[i]a[i]构成了2626个字母组成的排列。

    MGMG现在需要知道这个随机串变换到自身的期望变换次数。请你输出期望答案乘上26^n26
    ​n
    ​​ 以后模 10000000071000000007 的结果。

    MGMG认为这件事非常容易,不屑于用计算机解决,于是运用他高超的人类智慧开始进行计算。作为一名旁观者,你也想挑战MGMG智慧,请你写个程序,计算答案。
    输入描述
    第一行一个整数TT,代表数据组数(1 <=T<=101<=T<=10)。

    接下来,对于每组数据——

    第一行一个整数NN,表示给定的随机串长度(1<=N<=10000000001<=N<=1000000000)。

    第二行2626个字母,表示a_ia
    ​i
    ​​ 序列
    输出描述
    对于每一组数据,输出一行。

    显然,这个期望是一个实数。请你输出它乘上26^N26
    ​N
    ​​ 以后模 10000000071000000007 的结果
    输入样例
    2
    2
    abcdefghijklmnpqrstuvwxyzo
    1
    abcdefghijklmnopqrstuvwxyz
    输出样例
    5956
    26
     

    题解请参考这位大神:

    https://blog.csdn.net/junior19/article/details/71599520

    他的代码:

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<string>
    #include<vector>
    #include<deque>
    #include<queue>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<stack>
    #include<ctime>
    #include<string.h>
    #include<math.h>
    #include<list>
    
    using namespace std;
    
    #define ll long long
    #define pii pair<int,int>
    const int inf = 1e9 + 7;
    
    char to[27];
    bool vis[27];
    vector<pii>loop;//fist 循环节长度为first 有second个循环节长度为first
    
    void calLoop(){
        for(int i=0;i<26;++i){
            to[i]-='a';
        }
        map<int,int>mp;
        fill(vis,vis+27,0);
        loop.clear();
        for(int i=0;i<26;++i){
            if(vis[i]==0){
                vis[i]=1;
                int ans=1;
                int x=to[i];
                while(x!=i){
                    vis[x]=1;
                    ++ans;
                    x=to[x];
                }
                mp[ans]+=1;
            }
        }
        for(auto it=mp.begin();it!=mp.end();++it){
            loop.push_back(*it);
        }
    }
    
    ll lcm(ll a,ll b){
        ll tmp=__gcd(a,b);
        return a/tmp*b;
    }
    
    ll quickMulti(ll a,ll n){
        ll ans=1;
        ll t=a%inf;
        while(n){
            if(n&1){
                ans=(ans*t)%inf;
            }
            t=(t*t)%inf;
            n>>=1;
        }
        return ans;
    }
    
    inline ll mod(ll x){
        return (x%inf+inf)%inf;
    }
    
    ll f(vector<int>&vec,int n){//容斥
        ll ans=0;
        int nv=vec.size();
        for(int i=1,end=1<<nv;i<end;++i){
            ll flag=-1;
            int sum=0,num=0;
            for(int j=0;j<nv;++j){
                if((1<<j)&i){
                    sum+=vec[j];
                    ++num;
                }
            }
            if(num%2==nv%2){
                flag=1;
            }
            ll t=quickMulti(sum,n);
            ans=(ans+mod(flag*t))%inf;
        }
        return ans;
    }
    
    ll slove(int n){
        calLoop();
        ll ans=0;
        vector<int>vec;//当前选择了的循环节包含的字母数
        for(int i=1,end=1<<loop.size();i<end;++i){//枚举循环节的状态
            ll ans1=1;//选择了这几个循环节的贡献
            vec.clear();
            for(int j=0;j<loop.size();++j){
                if((1<<j)&i){
                    ans1=lcm(ans1,loop[j].first);
                    vec.push_back(loop[j].first*loop[j].second);
                }
            }
            if(vec.size()>n){
                continue;
            }
            ll ans2=f(vec,n);
            ans=(ans+ans1*ans2)%inf;
        }
        return ans;
    }
    
    int main()
    {
    //freopen("in.txt","r",stdin);
        //freopen("/home/lu/Documents/w.txt","w",stdout);
        int T;
        scanf("%d",&T);
        while(T--){
            int n;
            scanf("%d%s",&n,to);
            printf("%lld
    ",slove(n));
        }
        return 0;
    }
    
  • 相关阅读:
    CodeForces Round #678(Div2) E.Complicated Computations Mex性质,权值线段树
    P6075 子集选取 思维
    HDU-4747 Mex 线段树应用 Mex性质
    P1273 有线电视网 树形DP 树上背包
    P6786 GCDs & LCMs 数学推导
    [CTSC1997] 选课 树上背包
    Gym-101915K Poor Ramzi 区间DP
    [MdOI R2] Odyssey 拓扑排序上DP
    CodeForces Div3.F
    二分-B
  • 原文地址:https://www.cnblogs.com/linruier/p/9846322.html
Copyright © 2011-2022 走看看