“玲珑杯”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: ...
随机推荐
- 【小练习06】HTML+CSS--电影公告
要求实现如下效果图: 代码演示 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"&g ...
- python中的map、filter、reduce函数
三个函数比较类似,都是应用于序列的内置函数.常见的序列包括list.tuple.str. 1.map函数 map函数会根据提供的函数对指定序列做映射. map函数的定义: map(function ...
- Vue 非父子组件通信
组件是Vue核心的一块内容,组件之间的通信也是很基本的开发需求.组件通信又包括父组件向子组件传数据,子组件向父组件传数据,非父子组件间的通信.前两种通信Vue的文档都说的很清楚,但是第三种文档上确只有 ...
- 《Python编程从入门到实践》_第六章_字典
一个简单的字典 #用户信息 user = {','city':'shanghai'} print(user['name']) print(user['age']) print(user['city'] ...
- tomcat之 Tomcat 7.0.78 单机多实例配置
前言:JDK(JavaDevelopment Kit)是Sun Microsystems针对Java开发员的产品.自从Java推出以来,JDK已经成为使用最广泛的javaSDK. JDK是整个Java ...
- django ngRoute ui-router 开发环境下禁用缓存
问题描述: Python manage.py runserver ,禁用缓存,及时修改反馈到浏览器 解决办法: 使用dummy cache: Dummy caching (for developmen ...
- mysql+keepalived 双主热备高可用
理论介绍:我们通常说的双机热备是指两台机器都在运行,但并不是两台机器都同时在提供服务.当提供服务的一台出现故障的时候,另外一台会马上自动接管并且提供服务,而且切换的时间非常短.MySQL双主复制,即互 ...
- cmake的安装和卸载
cmake介绍: CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程).他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性 ...
- 大数据 Hadoop,Spark和Storm
大数据(Big Data) 大数据,官方定义是指那些数据量特别大.数据类别特别复杂的数据集,这种数据集无法用传统的数据库进行存储,管理和处理.大数据的主要特点为数据量大(Volume),数据类别复 ...
- 你应该知道的jQuery技巧【收藏】
jQuery的存在,让学习前端开发的人感到前端越来越容易入门了,用简单的几行代码就可以实现需求,但是,你真的会用jQuery么,当代码运行 后无法看到自己预期的效果,是不是觉得jQuery出了问题,其 ...