这个题的题解并不想写……一个写的很详细的blog

第1个测试点:mod=2,a[i]<mod(仔细看题),则n个数字都是1,直接输出1即可.

第2个测试点:每次乘上去的数字只有一种选择,快速幂即可.

第3,4,5个测试点:定义f[i][j]表示i次操作后x的数值为j的概率.直接转移,复杂度O(m*mod^2)

         f[][]=;
for(int i=;i<m;i++)
for(int j=;j<mod;j++)
for(int k=;k<mod;k++)//这里不要枚举n啊,可以先处理出来每个数出现的概率
f[i+][j*k%mod]=(f[i+][j*k%mod]+f[i][j]*v[k]%p)%p;

第6,7,8个测试点:第3,4,5个测试点中的DP转移可以转化为矩阵乘法形式,利用矩阵快速幂进行优化,复杂度O(mod^3*logm)矩阵快速幂优化dp见--->这里

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define int LL
#define MAXN 100010
#define LL long long
using namespace std;
struct jz
{
LL m[][];
void clear(){memset(m,,sizeof(m));}
}base;
int n,m,mod,a[MAXN];
const int p=1e9+;
jz operator * (jz &a,jz &b)
{
jz ans;ans.clear();
for(int i=;i<mod;i++)
for(int j=;j<mod;j++)
for(int k=;k<mod;k++)
ans.m[i][j]=(ans.m[i][j]+a.m[i][k]*b.m[k][j]);
for(int i=;i<mod;i++)
for(int j=;j<mod;j++)
ans.m[i][j]%=p;
return ans;
}
jz operator ^ (jz a,int b)
{
jz ans=a;b--;
while(b)
{
if(b&)ans=ans*a;
a=a*a;
b=b>>;
}
return ans;
}
LL f[][],tem;
LL v[];
LL poww(LL a,int b,int mod)
{
LL ans=;
while(b)
{
if(b&)ans=ans*a%mod;
a=a*a%mod;
b=b>>;
}
return ans;
}
signed main()
{
// freopen("in.txt","r",stdin);
// freopen("0.out","w",stdout); cin>>n>>m>>mod;tem=poww(n,p-,p);
for(int i=;i<=n;i++)cin>>a[i],v[a[i]%mod]=(v[a[i]%mod]+tem)%p;
if(mod==){puts("");return ;}
if(n==){printf("%lld\n",poww(a[],m,mod));return ;}
if(m<=)
{
f[][]=;
for(int i=;i<m;i++)
for(int j=;j<mod;j++)
for(int k=;k<mod;k++)
f[i+][j*k%mod]=(f[i+][j*k%mod]+f[i][j]*v[k]%p)%p;
LL ans=;
for(int i=;i<mod;i++)
ans=(ans+f[m][i]*i%p)%p;
printf("%lld\n",ans%p);
}
else if(mod<=)
{
for(int j=;j<mod;j++)
for(int k=;k<mod;k++)
base.m[j*k%mod][j]=(base.m[j*k%mod][j]+v[k])%p;
base=base^m;
LL ans=;
for(int i=;i<mod;i++)
ans=(ans+base.m[i][]*i%p)%p;
printf("%lld\n",ans%p);
}
}

这里放出暴力dp和矩阵优化dp

第9,10个测试点(标算):上面那个blog讲的非常详细了(然而我并没有看懂……),总感觉这个矩阵优化dp怪怪的……

先把达哥题解放出来:

利用原根进行转化,则乘法转化为加法,f[i][j]表示i次操作后x取模后等于原根的j次方的概率.指数需要对(mod-1)取模.这样转化一下我们发现转移还是矩阵的形式,而且是循环矩阵的形式.循环矩阵快速幂,复杂度O(mod^2*logm)

然后是另一种标算(本人写的这个):

定义f[i][j]表示i次操作后变成原根的j次方的概率.求出p[i][j]表示2^i次操作后变成原根的j次方的概率.倍增的思想求出f[m][]这个数组.也是O(mod^2*logm)

     for(int i=;i<=mod-;i++)p[][i]=tem*cnt[i]%mp;//乘2^0为rt^i的概率,tem为分母的逆元,cnt为个数。
for(int i=;i<=;i++)
for(int j=;j<=mod-;j++)
for(int k=;k<=mod-;k++)
p[i][(j+k)%(mod-)]=(p[i][(j+k)%(mod-)]+p[i-][j]*p[i-][k]%mp)%mp;

然后用类似快速幂的方法就可以求出了,避免了直接理解矩阵。

 #include<iostream>
#include<cstdio>
#define MAXN 400010
#define LL long long
#define int LL
using namespace std;
const int mp=1e9+;
int n,m,mod,a[MAXN];
int xp[],cnt[];
int rt;
int p[][],f[][];
LL poww(LL a,int b,int mod)
{
LL ans=;
while(b)
{
if(b&)ans=ans*a%mod;
a=a*a%mod;
b=b>>;
}
return ans;
}
void findroot()
{
for(rt=;rt<mod;rt++)
{
bool pd=;
for(int i=;i<mod-;i++)
if(poww(rt,i,mod)==){pd=;break;}
if(pd||poww(rt,mod-,mod)!=)continue;
else break;
}
}
signed main()
{
cin>>n>>m>>mod;
findroot();int tem=poww(n,mp-,mp),x;
xp[]=;for(int i=;i<=mod;i++)xp[i]=xp[i-]*rt%mod;
for(int i=;i<=mod-;i++)a[xp[i]]=i;
for(int i=;i<=n;i++)cin>>x,cnt[a[x]]++;
for(int i=;i<=mod-;i++)p[][i]=tem*cnt[i]%mp;//乘2^0为rt^i的概率;
for(int i=;i<=;i++)
for(int j=;j<=mod-;j++)
for(int k=;k<=mod-;k++)
p[i][(j+k)%(mod-)]=(p[i][(j+k)%(mod-)]+p[i-][j]*p[i-][k]%mp)%mp;
f[][]=;
for(int k=;m;m/=,k++)
if(m&)
{
for(int i=;i<=mod-;i++)f[][i]=;
for(int i=;i<=mod-;i++)
for(int j=;j<=mod-;j++)
f[][(j+i)%(mod-)]=(f[][(j+i)%(mod-)]+f[][i]*p[k][j]%mp)%mp;
for(int i=;i<=mod-;i++)f[][i]=f[][i];
}
LL ans=;
for(int i=;i<=mod-;i++)ans=(ans+f[][i]*xp[i]%mp)%mp;
printf("%lld\n",ans);
}

完整代码

更加优越的算法(???):本质上我们要做的是循环卷积,可以使用fft.但本题的模数使得fft较为不方便..

HZOJ 随的更多相关文章

  1. hzoj 2301(莫比乌斯反演)

    题意 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公 数. 思路: 与先前的那个相比,这次a,c并不一定 ...

  2. HZOJ 单

    两个子任务真的是坑……考试的时候想到了60分的算法,然而只拿到了20分(各种沙雕错,没救了……). 算法1: 对于测试点1,直接n遍dfs即可求出答案,复杂度O(n^2),然而还是有好多同学跑LCA/ ...

  3. 20191102 「HZOJ NOIP2019 Round #12」20191102模拟

    先开坑. md原题写挂我也真是... 100+20+10 白夜 打表大法吼 显然,不在环上的点对答案的贡献是 \((k-cycle)^{k-1}\) . 打表得到环上的递推式,矩阵一下乘起来就好了. ...

  4. 20191004 「HZOJ NOIP2019 Round #9」20191004模拟

    综述 第一次 rk1 ,激动. 题目是 COCI 18/19 Round #1 的三至五题. 得分 \(100+100+20\) \(\mathrm{cipele}\) 问题描述 HZOJ1313 题 ...

  5. 20191003 「HZOJ NOIP2019 Round #8」20191003模拟

    综述 试题为常州集训2019SCDay2 得分\(100+30(0)+28\) 时之终结 问题描述 HZOJ1310 题解 构造题. 发现部分分有一档是 \(Y\) 是 \(2^x\) ,于是自然想到 ...

  6. 20190922 「HZOJ NOIP2019 Round #7」20190922模拟

    综述 这次是USACO2019JAN Gold的题目. \(\mathrm{Cow Poetry}\) 题解 因为每句诗的长度一定是\(k\),所以自然而然想到背包. 设\(opt[i][j]\)代表 ...

  7. HZOJ 20190819 NOIP模拟26题解

    考试过程: 照例开题,然后觉得三道题都挺难,比昨天难多了(flag×1),T1 dp?T2 数据结构? T3 dp?事实证明我是sb然后决定先搞T2,但是,woc,这题在说什么啊,我怎么看不懂题啊,连 ...

  8. HZOJ 20190818 NOIP模拟24题解

    T1 字符串: 裸的卡特兰数题,考拉学长讲过的原题,就是bzoj3907网格那题,而且这题更简单,连高精都不用 结论$C_{n+m}^{n}-C_{n+m}^{n+1}$ 考场上10min切掉 #in ...

  9. HZOJ 20190727 随(倍增优化dp)

    达哥T1 实际上还是挺难的,考试时只qj20pts,还qj失败 因为他专门给出了mod的范围,所以我们考虑把mod加入时间复杂度. $50\%$算法: 考虑最暴力的dp,设$f[i][j]$表示进行$ ...

  10. HZOJ 20190727 T2 单(树上dp+乱搞?+乱推式子?+dfs?)

    考试T2,考试时想到了40pts解法,即对于求b数组,随便瞎搞一下就oxxk,求a的话,很明显的高斯消元,但考试时不会打+没开double挂成10pts(我真sb),感觉考试策略还是不够成熟,而且感觉 ...

随机推荐

  1. Web三大组件之控制器组件Servlet(转载)

    Servlet:主要用于处理客户端传来的请求,并返回响应.获取请求数据>处理请求>完成响应 过程:客户端发送请求----HTTP服务器接收请求,HTTP服务器只负责解析静态HTML界面,其 ...

  2. Lua 调用C模块DLL失败

    Lua中使用 local a = require "xxx" 的方式加载自己用C实现的DLL,DLL中有导出函数 luaopen_xxx . 调试过程中发现,luaopen_xxx ...

  3. deque简单解析

    deque是支持双端插入删除的容器,oi中用来维护单调队列 声明方式 deque<int> d1;//声明一个叫d1的双向队列 deque<int> d2(d1);//声明一个 ...

  4. Vue--系统指令(基础)

    Vue概念:vue是mvvm模式的,直接操作dom开销较大,先获取dom,修改里边的内容,但是用vue的话,直接视图和模型绑定,不管是视图的数据发生改变还是模型的数据发生改变,其都是关联的,不需要直接 ...

  5. toString方法和valueof()方法的区别

    JavaScript引用类型之Array数组的toString()和valueof()方法的区别   一.转换方法 1.在JavaScript中几乎所有对象都具有toLocaleString().to ...

  6. 机器学习之Adaboost算法原理

    转自:http://www.cnblogs.com/pinard/p/6133937.html 在集成学习原理小结中,我们讲到了集成学习按照个体学习器之间是否存在依赖关系可以分为两类,第一个是个体学习 ...

  7. Lichee ( 四 ) 打包IMAGE

    在<Lichee(三) Android4.0的目标产品文件夹与Lichee的纽带---extract-bsp>中我们分析了extract-bsp的作用和意义.到这里,我们能够開始编译And ...

  8. Direct2D 第4篇 渐变画刷

    原文:Direct2D 第4篇 渐变画刷 #include <windows.h> #include <d2d1.h> #include <d2d1helper.h> ...

  9. 来自 Spring Cloud 官方的消息,Spring Cloud Alibaba 即将毕业

    2019 年 7 月 24 日晚,Spring Cloud 官方发布公告: 仓库迁移是官方决定 Spring Cloud Alibaba 即将毕业 根据官方最新的发版规则,我们会把孵化器中的 Spri ...

  10. Spring_使用(JDBC)

    Spring_对JDBC的支持 使用JdbcTemplate更新数据库 导入jar包 创建applicationcontext.xml <?xml version="1.0" ...