“玲珑杯”ACM比赛 Round #12 (D) 【矩阵快速幂的时间优化】
//首先,感谢Q巨
定义状态向量b[6]
b[0]:三面临红色的蓝色三角形个数
b[1]:两面临红色且一面临空的蓝色三角形个数
b[2]:一面临红色且两面临空的蓝色三角形个数
b[3]:三面临红色的黄色三角形个数
b[4]:两面临红色且一面临绿+的黄色三角形个数
b[5]:一面临红色且两面临绿+的黄色三角形个数
转移矩阵:
[3 1 0 0 0 0;
0 2 2 0 0 0;
0 1 3 0 0 0;
3 2 1 0 0 0;
0 0 0 6 3 0;
0 0 0 0 2 4]
最朴素的TLE代码
#include<bits/stdc++.h> using namespace std; typedef long long LL; ; ; LL b[N]= {,,,,,}; //此处初始化列向量 LL hh[N][N]={{,,,,,}, {,,,,,}, {,,,,,}, {,,,,,}, {,,,,,}, {,,,,,} }; struct Mat { LL mat[N][N]; } A; Mat Mut(Mat a,Mat b) { Mat c; memset(c.mat,,sizeof(c.mat)); ; k<N; k++) ; i<N; i++) if(a.mat[i][k]) ; j<N; j++) { c.mat[i][j]+=a.mat[i][k]*b.mat[k][j]%mod; c.mat[i][j]=c.mat[i][j]%mod; } return c; } Mat Qpow(Mat a,LL n) { Mat c; ; i<N; ++i) ; j<N; ++j) c.mat[i][j]=(i==j); ) { ) c=Mut(c,a); a=Mut(a,a); } return c; } void cal(Mat A,LL n,LL b[],LL& Fn,LL& Gn) { Mat A_=Qpow(A,n-); Fn=Gn=; LL c[N]={}; ;i<N;i++) ;j<N;j++) c[i]=(c[i]+A_.mat[i][j]*b[j])%mod; Fn=(c[]+c[]+c[])%mod; Gn=(c[]+c[]+c[])%mod; } void init_A() { ;i<N;i++) ;j<N;j++) A.mat[i][j]=hh[i][j]; } int main() { LL n,Fn,Gn; init_A(); while(cin>>n) { ) { puts("1 0"); continue; } n--; cal(A,n,b,Fn,Gn); cout<<Fn<<' '<<Gn<<endl; } }
貌似(只是貌似)被优化但仍然TLE的代码
#include<bits/stdc++.h> using namespace std; typedef long long LL; ; ; LL b[N]= {,,,,,}; //此处初始化列向量 LL hh[N][N]={{,,,,,}, {,,,,,}, {,,,,,}, {,,,,,}, {,,,,,}, {,,,,,} }; struct Mat { LL mat[N][N]; } A,F[]; void printM(Mat x) { puts("================================================================="); ;i<N;i++) { ;j<N;j++) printf("%10lld",x.mat[i][j]); puts(""); } } Mat Mut(Mat a,Mat b) { Mat c; memset(c.mat,,sizeof(c.mat)); ; k<N; k++) ; i<N; i++) if(a.mat[i][k]) ; j<N; j++) { c.mat[i][j]+=a.mat[i][k]*b.mat[k][j]%mod; c.mat[i][j]=c.mat[i][j]%mod; } return c; } Mat Qpow(Mat a,LL n) { Mat c; ; i<N; ++i) ; j<N; ++j) c.mat[i][j]=(i==j); ) { ) c=Mut(c,a); a=Mut(a,a); } return c; } void cal(Mat A,LL n,LL b[],LL& Fn,LL& Gn) { Mat A_; ; i<N; ++i) ; j<N; ++j) A_.mat[i][j]=(i==j); ;i<&&n;i++,n>>=) ) A_=Mut(A_,F[i]); //printM(A_); Fn=Gn=; LL c[N]={}; ;i<N;i++) ;j<N;j++) c[i]=(c[i]+A_.mat[i][j]*b[j])%mod; Fn=(c[]+c[]+c[])%mod; Gn=(c[]+c[]+c[])%mod; } void init_A() { ;i<N;i++) ;j<N;j++) A.mat[i][j]=hh[i][j]; F[]=A; ;i<;i++) F[i]=Mut(F[i-],F[i-]); } int main() { LL n,Fn,Gn; init_A(); int T; // cin>>T; scanf("%lld",&T); while(T--) { // cin>>n; scanf("%lld",&n); ) { puts("1 0"); continue; } n-=; cal(A,n,b,Fn,Gn); // cout<<Fn<<' '<<Gn<<endl; printf("%lld %lld\n",Fn,Gn); } }
矩阵相乘一次的复杂度是O(N^3)的,不过预处理2^i(i:0~60)的矩阵后,可以用向量记录中间结果,而矩阵*向量的复杂度为O(N^2)
最终复杂度: O(T * lb(n) * N^2)->O(1e5 * 60 * 36)->O(2e8)
最终可以AC的代码
#include<bits/stdc++.h> using namespace std; typedef long long LL; ; ; LL b[N]= {,,,,,}; //此处初始化列向量 LL hh[N][N]={{,,,,,}, {,,,,,}, {,,,,,}, {,,,,,}, {,,,,,}, {,,,,,} }; struct Mat { LL mat[N][N]; } A,F[]; void printM(Mat x) { puts("================================================================="); ;i<N;i++) { ;j<N;j++) printf("%10lld",x.mat[i][j]); puts(""); } } Mat Mut(Mat a,Mat b) { Mat c; memset(c.mat,,sizeof(c.mat)); ; k<N; k++) ; i<N; i++) if(a.mat[i][k]) ; j<N; j++) { c.mat[i][j]+=a.mat[i][k]*b.mat[k][j]%mod; c.mat[i][j]=c.mat[i][j]%mod; } return c; } Mat Qpow(Mat a,LL n) { Mat c; ; i<N; ++i) ; j<N; ++j) c.mat[i][j]=(i==j); ) { ) c=Mut(c,a); a=Mut(a,a); } return c; } void cal(Mat A,LL n,LL b[],LL& Fn,LL& Gn) { Mat A_; LL c[N]={,,,,,}; ; i<N; ++i) ; j<N; ++j) A_.mat[i][j]=(i==j); ;i<&&n;i++,n>>=) ) { LL tres[]={,,,,,}; ;j<;j++) //矩阵的行 ;k<;k++) //矩阵的列 tres[j]=(tres[j]+F[i].mat[j][k]*c[k])%mod; ;j<;j++) c[j]=tres[j]%mod; } Fn=Gn=; Fn=(c[]+c[]+c[])%mod; Gn=(c[]+c[]+c[])%mod; } void init_A() { ;i<N;i++) ;j<N;j++) A.mat[i][j]=hh[i][j]; F[]=A; ;i<;i++) F[i]=Mut(F[i-],F[i-]); } int main() { LL n,Fn,Gn; init_A(); int T; scanf("%lld",&T); while(T--) { scanf("%lld",&n); ) { puts("1 0"); continue; } n-=; cal(A,n,b,Fn,Gn); printf("%lld %lld\n",Fn,Gn); } }
“玲珑杯”ACM比赛 Round #12 (D) 【矩阵快速幂的时间优化】的更多相关文章
- “玲珑杯”ACM比赛 Round #12题解&源码
我能说我比较傻么!就只能做一道签到题,没办法,我就先写下A题的题解&源码吧,日后补上剩余题的题解&源码吧! A ...
- “玲珑杯”ACM比赛 Round #18
“玲珑杯”ACM比赛 Round #18 Start Time:2017-07-15 12:00:00 End Time:2017-07-15 15:46:00 A -- 计算几何你瞎暴力 Time ...
- “玲珑杯”ACM比赛 Round #19题解&源码【A,规律,B,二分,C,牛顿迭代法,D,平衡树,E,概率dp】
A -- simple math problem Time Limit:2s Memory Limit:128MByte Submissions:1599Solved:270 SAMPLE INPUT ...
- “玲珑杯”ACM比赛 Round #19 B -- Buildings (RMQ + 二分)
“玲珑杯”ACM比赛 Round #19 Start Time:2017-07-29 14:00:00 End Time:2017-07-29 16:30:00 Refresh Time:2017-0 ...
- “玲珑杯”ACM比赛 Round #1
Start Time:2016-08-20 13:00:00 End Time:2016-08-20 18:00:00 Refresh Time:2017-11-12 19:51:52 Public ...
- SCUT - 12 - 西方国家 - 矩阵快速幂
https://scut.online/p/12 可以用矩阵快速幂来做. #include<bits/stdc++.h> using namespace std; typedef long ...
- poj 3735 Training little cats 矩阵快速幂+稀疏矩阵乘法优化
题目链接 题意:有n个猫,开始的时候每个猫都没有坚果,进行k次操作,g x表示给第x个猫一个坚果,e x表示第x个猫吃掉所有坚果,s x y表示第x个猫和第y个猫交换所有坚果,将k次操作重复进行m轮, ...
- “玲珑杯”ACM比赛 Round #13 题解&源码
A 题目链接:http://www.ifrog.cc/acm/problem/1111 分析:容易发现本题就是排序不等式, 将A数组与B数组分别排序之后, 答案即N∑i=1Ai×Bi 此题有坑,反正据 ...
- POJ 3735 Training little cats<矩阵快速幂/稀疏矩阵的优化>
Training little cats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13488 Accepted: ...
随机推荐
- canvas——随机生成迷宫
先上图. 效果 代码 随机生成迷宫要求任意两点都能够找到相同的路径,也就是说,迷宫是一个连通图.随机生成迷宫可以使用普里姆算法.广度优先算法.深度优先算法等实现.这里将使用普里姆算法通过生成最小数的方 ...
- vue-cli webpack在node环境下安装使用
第一步,需要下载并安装node.js以及他的npm组件: 第二步,用node -v;npm -v来测试node.js以及npm是否安装成功(建议用GIT命令行工具,因为GIT是linux系统),如果显 ...
- Top 10 JavaScript编辑器,你在用哪个?
对于JavaScript程序员来说,目前有很多很棒的工具可供选择.文本将会讨论10个优秀的支持JavaScript,HTML5和CSS开发,并且可以使用Markdown进行文档编写的文本编辑器.为什么 ...
- bootstrap之daterangepicker---汉化以及扩展
一.扩展的功能 1.初始化时,会自动创建一个select标签: 2.当改变select值时,日期也会自动改变,并且会调用apply按钮的click事件 3.点击此处进行预览 4.github地址:ht ...
- Ajax请求,跨域小坑
今天在上班的时候,被坐在旁边项目经理叫过去问了一个Ajax请求跨域的问题,一开始没理解清楚也还有对这个没有理解的透,后面被打击的要死. 当时的需求是需要测试一个已发布的api接口,需要在本地写测试程序 ...
- maven插件打包可执行jar
pom文件加 <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</grou ...
- c# networkcomms 3.0实现模拟登陆总结
最近项目需要做一个客户查询状态系统,当前上位机缺少服务功能,于是找到了networkcomms 开源框架,作为项目使用. 最新版networkcomms 下载地址:https://github.com ...
- thinkphp获取特定字段的两种方法
thinkphp getField( )和field( ) 2014年10月05日 ⁄ 综合 ⁄ 共 1509字 ⁄ 字号 小 中 大 ⁄ 评论关闭 做数据库查询的时候,比较经常用到这两个,总是查手册 ...
- Mysql数据库存储emoji表情
emoji表情需要使用编码格式未utf8mb4,mysql数据库版本要5.5以上,我用的是5.6,因为只有5.5以上支持utf8mb4. 1.数据库编码设定为utf8mb4,如果建库时指定的是utf8 ...
- css透明度的设置
Css代码 .transparent_class { filter:alpha(opacity=50); -moz-opacity:0.5; -khtml-opacity: 0.5; opacity: ...