“玲珑杯”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: ...
随机推荐
- 一天搞定CSS:初识css--01
1)CSS:层叠样式表(英文全称:Cascading Style Sheets) 是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一个子集)等文件样式的计算机语言. C ...
- js创建对象的多种方式及优缺点
在js中,如果你想输入一个的信息,例如姓名,性别,年龄等,如果你用值类型来存储的话,那么你就必须要声明很多个变量才行,变量声明的多了的话,就会造成变量污染.所以最好的方式就是存储到对象中.下面能我就给 ...
- shared_ptr注意点
1.原始指针不能直接使用赋值运算符对shared_ptr进行赋值运算 std::shared_ptr<int> p; p= ); //error p.reset(); //success ...
- map | make_pair
#include <map> void func(std::map<int,std::pair<const char*,int>> &T_map) { st ...
- 自动适配H5容器(UIViewView/WKWebView),生成长图,防微信进度条
前段时间撸代码猥琐发育的时候,设计师老王给了张截图某宝APP上一个生成长图分享的功能,正好公司有这个需求,于是在立马开始操练起来!在万能的度娘上搜集整理资料后发现很多文章介绍的方案对WKWebView ...
- Python os模块--路径、文件、系统命令等操作
os模块包含普遍的操作系统功能. 注意:函数参数path是文件或目录的路径,filename是文件的路径,dirname是目录的路径,路径可以是相对路径,也可绝对路径 常见或重要的函数为加粗字体 os ...
- 关于JS数组的定义
关于js数组的定义的一些内容: 数组是一个对象 只用一个变量,储存多个同类型的信息 数组--连续的储存空间 数组的下标从0开始 ps:定义一个数组可以看作是一个旅馆.里面有很多小房子. 1.创建数组- ...
- Matlab: 路径的操作
添加相对路径 在matlab中当代码很多时常常将结果存在不同的文件夹下面,常常使用相对路径对函数进行调用,但有时会存在问题.举个栗子: 代码结构如下: /codes/A/AA/code1.m /cod ...
- 【node】记录项目的开始与完成——pipeline_kafka流式数据库管理项目
前言: 我始终坚信的一点是,学习的效果80%来自总结,甚至全部都是.总结的好处就是让你能翻出你的过往,指出其中的不足,看到未来的改进方法,好的总结更能让知识产生飞跃,所以在工作之余,部署项目之际,总结 ...
- URL重定向
/** * URL重定向 * @param string $url 重定向的URL地址 * @param integer $time 重定向的等待时间(秒) * @param string $msg ...