[CSP-S模拟测试]:山洞(DP+快速幂)
题目传送门(内部题17)
输入格式
一行两个整数$n$,$m$,含义如题面。
输出格式
一行一个整数,表示方案数模$1e9+7$。
样例
样例输入1:
4 6
样例输出1:
0
样例输入2:
707 185547
样例输出2:
588828156
数据范围与提示
对于$20\%$的数据,$m\leqslant 20$。
对于$60\%$的数据,$m\leqslant 1,000$。
对于$100\%$的数据,$m\leqslant 1e9,n\leqslant 1,000$。
题解
这道题原题题意有误,我在上面已经做了修改。
$40\%$算法:
直接输出$0$就好啦,我也很震惊居然有这么多分~
时间复杂度:$\Theta(1)$。
期望得分:$0$分。
实际得分:$40$分。
$60\%$算法:
设$dp[i][j]$表示在第$i$步到$j$的方案数,那么很轻松的就能列出状态转移方程:$dp[i][j]=dp[i-1][j-i]+dp[i-1][j+i]$。
时间复杂度:$\Theta(n\times m)$。
期望得分:$60$分。
实际得分:$60$分(结合上面的“算法”可以得到$80$分)。
$100\%$算法:
发现我们可以只预处理出来前$n$步的情况,然后用快速幂处理$\left \lceil \frac{m}{n}\right \rceil$次,后$m\mod n$步再暴力走完,时间复杂度不允许?循环矩阵哇,可以感性的理解为将步数向右推一位。
时间复杂度:$\Theta(n^2\times \log m)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
long long n,m;
long long dp[1001][1001];
long long wzc[1001],flag[1001],ans[1001];
void matrix1()
{
for(long long i=0;i<n;i++)flag[i]=ans[i],ans[i]=0;
for(long long i=0;i<n;i++)
for(long long j=0;j<n;j++)
ans[(i+j)%n]=(ans[(i+j)%n]+flag[i]*wzc[j]%1000000007)%1000000007;
}
void matrix2()
{
for(long long i=0;i<n;i++)flag[i]=wzc[i],wzc[i]=0;
for(long long i=0;i<n;i++)
for(long long j=0;j<n;j++)
wzc[(i+j)%n]=(wzc[(i+j)%n]+flag[i]*flag[j]%1000000007)%1000000007;
}
int main()
{
scanf("%lld%lld",&n,&m);
dp[0][0]=1;
for(long long i=1;i<=n;i++)
for(long long j=0;j<n;j++)
{
if((j-i+n)%n==(j+i)%n)dp[i][j]=dp[i-1][(j+i)%n];
else dp[i][j]=(dp[i-1][(j-i+n)%n]+dp[i-1][(j+i)%n])%1000000007;
}
for(long long i=0;i<n;i++)
wzc[i]=dp[n][i];
ans[0]=1;
long long bs=m/n;
while(bs)
{
if(bs&1)matrix1();
matrix2();
bs>>=1;
}
bs=m%n;
for(long long i=0;i<n;i++)
dp[0][i]=ans[i];
for(long long i=1;i<=bs;i++)
for(long long j=0;j<n;j++)
{
if((j-i+n)%n==(j+i)%n)dp[i][j]=dp[i-1][(j+i)%n];
else dp[i][j]=(dp[i-1][(j-i+n)%n]+dp[i-1][(j+i)%n])%1000000007;
}
printf("%lld",dp[bs][0]);
return 0;
}
rp++
[CSP-S模拟测试]:山洞(DP+快速幂)的更多相关文章
- [CSP-S模拟测试]:随(快速幂+数学)
题目描述 给出$n$个正整数$a_1,a_2...a_n$和一个质数mod.一个变量$x$初始为$1$.进行$m$次操作.每次在$n$个数中随机选一个$a_i$,然后$x=x\times a_i$.问 ...
- 【bzoj4870】[Shoi2017]组合数问题 dp+快速幂/矩阵乘法
题目描述 输入 第一行有四个整数 n, p, k, r,所有整数含义见问题描述. 1 ≤ n ≤ 10^9, 0 ≤ r < k ≤ 50, 2 ≤ p ≤ 2^30 − 1 输出 一行一个整数 ...
- 【11.1校内测试】【快速幂DP】【带权并查集】【模拟】
Solution $jzy$大佬用了给的原根的信息,加上矩阵快速幂150行QAQ 然而$yuli$大佬的做法不仅好懂,代码只有50行! 快速幂的思想,把m看成要组成的区间总长度,每次将两段组合得到新的 ...
- 2018.10.19 NOIP模拟 硬币(矩阵快速幂优化dp)
传送门 不得不说神仙出题人DZYODZYODZYO出的题是真的妙. f[i][j][k]f[i][j][k]f[i][j][k]表示选的硬币最大面值为iii最小面值不小于jjj,总面值为kkk时的选法 ...
- BZOJ.4818.[SDOI2017]序列计数(DP 快速幂)
BZOJ 洛谷 竟然水过了一道SDOI!(虽然就是很水...) 首先暴力DP,\(f[i][j][0/1]\)表示当前是第\(i\)个数,所有数的和模\(P\)为\(j\),有没有出现过质数的方案数. ...
- poj 3744 概率dp 快速幂 注意排序 难度:2
/* Scout YYF I Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5304 Accepted: 1455 De ...
- 2018.08.30 NOIP模拟 kfib(矩阵快速幂+exgcd)
[输入] 一行两个整数 n P [输出] 从小到大输出可能的 k,若不存在,输出 None [样例输入 1] 5 5 [样例输出] 2 [样例解释] f[0] = 2 f[1] = 2 f[2] = ...
- BZOJ3209 花神的数论题 【组合数学+数位DP+快速幂】*
BZOJ3209 花神的数论题 Description 背景 众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦. 描述 话说花神这天又来讲课了.课后照例有 ...
- Codeforces 935 简单几何求圆心 DP快速幂求与逆元
A #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #def ...
随机推荐
- pycharm常用快捷键 --- keymap==ecplise
F5 进入函数逐行调试 F6 执行完一行代码 F8 执行到下一个断点处 ctrl + d --删除一行代码 ALT + 上/下 箭头 代码上下移动 ALT + 左/右 箭头 左--返回 ...
- python字符串常见操作
字符串常见操作 如有字符串mystr = 'hello world itcast and itcastcpp',以下是常见的操作 <1>find 检测 str 是否包含在 mystr中,如 ...
- Notepad++正则表达式合并多行代码为1行
有时候你想要缩减代码行数,多行并1行,像网页流行的JS代码,查看时多见这种情况,但是有时你想把多行switch case缩成1行,再手动分开,每个case一行. 这种对齐方式似乎在日式程序员的代码中经 ...
- 《STL源码剖析》——第一、二、三章
第一章:概论: 换句话说,STL所实现的,是依据泛型思维架设起来的一个概念结构.这个以抽象概念(abstract concepts)为主体而非以实际类(classes)为主体的结构,形成了一个严谨的 ...
- python pip报错pip._ vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out.
AttributeError: module 'pip' has no attribute 'main报错 找到安装目录下 helpers/packaging_tool.py文件,找到如下代码: de ...
- JSP基础--javaBean
JavaBean 1 JavaBean概述 1.1 什么是JavaBean JavaBean是一种规范,也就是对类的要求.它要求Java类的成员变量提供getter/setter方法,这样的成员变量被 ...
- vscode内置c++ define选项
https://stackoverflow.com/questions/46415076/how-can-i-define-macros-for-the-c-intellisense-engine
- [Linux] 020 RPM 包的命名原则与其依赖性
1. RPM 包命名原则 例如:httpd-2.2.15-15.e16.centos.1.i686.rpm 字符 释义 httpd 软件包名 2.2.15 软件版本 15 软件发布的次数 e16.ce ...
- python面试题之如何读取大文件
① 利用生成器generator ②迭代器进行迭代遍历:for line in file 文章转载自Python黑洞网
- Codeforces - 1194E - Count The Rectangles - 扫描线
https://codeforc.es/contest/1194/problem/E 给5000条正常的(同方向不会重叠,也不会退化成点的)线段,他们都是平行坐标轴方向的,求能组成多少个矩形. 先进行 ...