zoukankan      html  css  js  c++  java
  • 【NOIP模拟赛】随

    题目链接:

      172.18.111.252:800/problem.php?cid=1001&pid=0

    题解:

      膜达神……(NOIP考这个就等爆零吧……)

      显然我们得到一个结论:$ans=sum_{i=0}^{mod-1}i*f_{i}$,其中$f_{i}$表示结果为i的概率。

      那么问题就是求$f_{i}$。

      最初我们可以想到用暴力枚举所有状态,显然超时,怎么优化,矩阵dp。可以开一个$n^{2}$的矩阵来递推。但这样时间$n^{3}log(n)$还是过不去。深入探讨,我们发现,给的mod是很小的,也就意味着可以把许多$a_{i}$合并概率,同时我们发现(题目下面提示),这原根似乎没用到。(⊙v⊙)嗯。

      我们设$g$为原根,那么对于所有的$a_{i}$我们都可以用$g^{x}$来表示,然后结合欧拉定理,我们就可以到到一个新的递推式:$f_{i,j}=sum_{x=0}^{mod-2}f_{i-1,x}*f_{i-1,j-x}$其中$f_{i,j}$表示i次选取后,结果为原根的j次幂的概率,$j-x$为其在mod-1意义下的剩余系。这个式子显然可以矩阵优化,同时我们发现这个矩阵是一个循环矩阵,然后我们就可以在$O(mod^{2}log(m))$的时间内求出答案。

     1 #include <cstdio>
     2 #include <cstring>
     3 using namespace std;
     4 const int mod=int(1e9)+7,N=1010;
     5 inline int read(){
     6     int s=0;char ch=getchar();
     7     while(ch<'0'||ch>'9')   ch=getchar();
     8     while(ch>='0'&&ch<='9') s=s*10+(ch^48),ch=getchar();
     9     return s;
    10 }
    11 int n,m,P,P2;
    12 int yuan(){
    13     for(int i=1;i<P;i++){
    14         int x=1;
    15         bool flag=true;
    16         for(int j=1;j<P2;j++){
    17             x=x*i%P;
    18             if(x==1){
    19                 flag=false;break;
    20             }
    21         }
    22         if(flag)    return i;
    23     }
    24 }
    25 inline int powmod(int a,int b){
    26     int ans=1;
    27     while(b){
    28         if(b&1) ans=1LL*ans*a%mod;
    29         b>>=1;
    30         a=1LL*a*a%mod;
    31     }return ans;
    32 }
    33 struct Matrix{
    34     int a[N];
    35     Matrix (){memset(a,0,sizeof(a));}
    36 }now,a;
    37 Matrix t;
    38 int pi[N],logs[N];
    39 int cnt[N];
    40 int main(){
    41     n=read(),m=read(),P=read();P2=P-1;
    42     int rt=yuan();
    43     
    44     int x=1;
    45     logs[1]=0;
    46     pi[0]=1;
    47     for(int i=1;i<P2;i++){
    48         x=1LL*x*rt%P;
    49         pi[i]=x;
    50         logs[x]=i;
    51     }
    52     for(int i=1;i<=n;i++)
    53         cnt[logs[read()]]++;
    54     
    55     int re=powmod(n,mod-2);
    56     for(int i=0;i<P2;i++)
    57         cnt[i]=1LL*cnt[i]*re%mod;
    58     now.a[0]=1;
    59     for(int i=0;i<P2;i++)
    60         a.a[i]=cnt[(P2-i)%P2];
    61     while(m){
    62         if(m&1) {
    63             for(int i=0;i<P2;i++){
    64                 t.a[i]=0;
    65                 for(int j=0;j<P2;j++)
    66                     t.a[i]=(1LL*t.a[i]+1LL*now.a[j]*a.a[(i-j+P2)%P2])%mod;
    67             }
    68             now=t;
    69         }
    70         m>>=1;
    71         for(int i=0;i<P2;i++){
    72             t.a[i]=0;
    73             for(int j=0;j<P2;j++)
    74                 t.a[i]=(1LL*t.a[i]+1LL*a.a[j]*a.a[(i-j+P2)%P2])%mod;
    75         }
    76         a=t;
    77     }
    78     int ans=0;
    79     for(int i=0;i<P2;i++){
    80            ans=(ans*1LL+pi[i]*1LL*now.a[(P2-i)%P2]%mod)%mod;
    81     }
    82     printf("%d
    ",ans);
    83 }
  • 相关阅读:
    6. 模块picklejson andomoszipfile面对对象(类的封装 操作 __init__)
    xlwt模块,(Excel表格)
    5. 迭代器生成器高阶函数推导式内置函数模块(math.time)
    4. 函数参数变量闭包递归
    3. 深浅拷贝/格式化/字符串/列表/字典/集合/文件操作
    2. 运算/循环/字符串操作
    1. 变量/数据类型
    Puppet自动化部署-安装及配置(3)
    Puppet自动化部署-前期环境准备(2)
    Puppet自动化运维-资源介绍篇(4)
  • 原文地址:https://www.cnblogs.com/Troywar/p/7448820.html
Copyright © 2011-2022 走看看