浅谈秦九韶算法
Posted 2020fengziyang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈秦九韶算法相关的知识,希望对你有一定的参考价值。
浅谈秦九韶算法
好像FFT要用到,所以就学习一下
听说还是高中必修三的内容?
秦九韶算法的应用:
当我们知道 \\(x\\) 的值时,求下列式子的值:
\\[f(x) = a_0 + a_1x + a_2x^2 + a_3x^3 + \\cdots + a_n - 1x^n - 1 + a_nx^n
\\]
一开始看到这个式子,我们肯定会想到直接带 \\(x\\) 进去乘不就行了吗
那秦九韶还提出来干什么
我们发现单单一个 \\(x^n\\) 就需要 \\(n - 1\\) 次乘法,那么一共就需要 \\(\\sum_i = 1 ^ n - 1i\\) 次乘法,和 \\(n\\) 次加法,如下 \\(n = 5\\) 时:
\\[f(x) = a_0 + a_1x + a_2x + a_3x + a_4x + a_5x
\\]
就需要 \\(10\\) 次乘法和 \\(5\\) 次加法。
显然这个十分复杂,所以才要用到奏九韶算法
秦九韶算法就是将上述式子一步步化简成如下式子:
\\[f(x) = ( \\cdots (a_nx + a_n - 1)x + a_n - 2)x + \\cdots + a_1)x + a_0
\\]
我们发现这个虽然还是要用到 \\(n\\) 次加法,但是乘法次数下降到了 \\(n - 1\\) 次,所以这个只需要 \\(O(n)\\)的时间就可以实现了。
code
代码十分短
void qinjiushao()
for(int i=n-1;i>=1;i--)
ans*=x,ans+=a[i];
如果人生会有很长,愿有你的荣耀永不散场
hdu6761 Mininum Index // lyndon分解 + duval贪心 + 秦九韶算法
link:http://acm.hdu.edu.cn/showproblem.php?pid=6761
建议学习该博客:https://blog.csdn.net/wayne_lee_lwc/article/details/107528945 √
AC代码:(基本搬运...看了半天才懂了一点点...还要好好深入理解)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
//#include<iomanip>
#include<cstdio>
#include<string>
#define ll long long
using namespace std;
const int maxn = 2e7+10;
const int m = 1e9+7;
int n;
int pos[maxn];//记录以i为结尾的前缀串中,字典序最小的后缀的首字符的下标
char s[maxn];
void lyndon_duval()
{
int i = 0,j,k;//i j k
while(i < n){
k = i;
j = i + 1;
//凡是与pos数组有关的下标皆需改动
while(j < n && s[j] >= s[k]){
if(s[j] == s[k]){
pos[j] = pos[k] + j - k;
k++;
}else{
k = i;
pos[j] = i + 1;//此时为完整的lyndon串
}
j++;
}
while(i <= k){
i += j - k;
}
if(i == j && i < n){
pos[j] = i + 1;//完全分解の特判
}
}
}
void cal_out()
{
ll ans = 0;
for (int i = n - 1; i >= 0; i--) ans = (1112LL * ans + pos[i]) % m;//qjs
cout << ans << endl;
}
int main(){
int T;cin >> T;
while( T-- ){
scanf("
");//略略略
cin >> s;
n = strlen(s);//
pos[0] = 1;
lyndon_duval();
cal_out();
}
//慎用memset!//本来想保险一点memset一波,结果超时...
return 0;
}
以上是关于浅谈秦九韶算法的主要内容,如果未能解决你的问题,请参考以下文章