[来自liu_runda的爱] 随

写在前面:这道题浪费了我很长时间(鬼知道今天的考试难度递减的?)

10分算法:

我们观察这两句话:“第1个测试点:mod=2---对于全部测试点: 1<=ai<mod,mod为质数1<=mod<=1000”,这说明什么?说明mod==2时a[]全为1啊!

于是直接输出1即可,10分就开心地(于学长.pdf)拿到了。

20分算法:

n==1时用快速幂即可,结合上述算法,20分拿到。

50分算法:

设f[i][j]为进行完i个操作后为j的概率,于是就有:

(f[i][j]+=f[i-1][j*a[k]%p]*S%mod)%=mod;

 

 其实可以把把没个数的贡献放到一个桶里,这样复杂度就从O(n*m*mod)变为了O(n*mod*mod),在3,4,5测试点没给n范围的情况下法二显然更稳。

80分算法:

是个蜜汁算法:达哥题解说要用矩阵优化,但是复杂度O(mod^3*log2(m))我是过不去6,7,8测试点的~

但可以去问问kx大神https://www.cnblogs.com/hzoi-kx/

100分算法:

前置知识:原根(上网搜总能找到的)。

有了这个知识之后我们便可以依靠原根把乘法转换为加法了,

f[i][j]代表操作了2^i次的结果是原根的i次方的方案数,用倍增的思想O(mod^2*log2(m))转移即可

for(int i=1;i<=35;i++)
{
        for(int j=0;j<p;j++)
        {
                for(int k=0;k<p;k++)
                {
                        (f[(j+k)%(p-1)][i]+=f[j][i-1]*f[k][i-1]%mod)%=mod;
                }
        }
}

之后我们考虑如何把m拆开统计答案,

我原来想的是简单的模数一样的简单相加,但是不然,

以为这样相当于统计的是2^1, 2^3.....的答案累加,也就是说好几次操作分开进行。

所以是错的,正解是像预处理f数组一样处理,期望得分100分

posted @ 2019-07-27 21:42  ATHOSD  阅读(133)  评论(0编辑  收藏  举报