标签:hide 开始 alt 包含 pac math ret 简单 cin
最近感冒,大脑有点不好使,先是斐波那契函数,又来一个简单的数列都不会了。
先写一篇博客安慰一下这几天没有发博客的自己!
这种题型,都司空见惯了,看了下数据,一般模拟都会超时,再有,模拟大家都会,肯定不会让你模拟就过关。
数列,那么就可以有A(n)和S(n)的通项公式,我们可以直接求出我们需要的那一项,唯一需要注意的就是一旦数据过大,就会爆掉,为此我还用了快速乘,发现,没什么用,后来发现是知识不到位......
Mathtype敲公式很烦,博客园又不支持markdown,所以我就手打了。
好,现在我们知道A(1) = 1
- A(0) = 1;
- A(n) = n + A(n-1)
- A(n-1) = n-1 + A(n-2)
- A(n-2) = n-2 + A(n-3)
- ......
- A(2) = 2 + A(1)
- A(1) = 1 + A(0)
- A(0) = 0 + 1
很容易得到A(n) = A(0) + S(n)
其中,S(n)为等差数列n的前n项和。
关键在于,我们求A(2n)时,
不用再次求S(n),而是直接加上 n*n
这相当于之前的每一项都加上 n,这样数据就不会爆掉。
A(2n) = A(n) + s(n) + n*n
1 /* 2 - A(0) = 1; 3 - A(n) = n + A(n-1) 4 - A(n-1) = n-1 + A(n-2) 5 - A(n-2) = n-2 + A(n-3) 6 - ...... 7 - A(2) = 2 + A(1) 8 - A(1) = 1 + A(0) 9 - A(0) = 0 + 1 10 */ 11 #include<iostream> 12 #include<cstring> 13 using namespace std; 14 15 typedef long long ll; 16 17 // 快乘 18 ll QMul(ll a, ll b) 19 { 20 if(a < b) {a ^= b;b ^= a;a ^= b;} 21 ll s = 0; 22 while(b) 23 { 24 if(b&1) s += a; 25 a = (a<<1); 26 b >>= 1; 27 } 28 return s; 29 } 30 31 int main() 32 { 33 ll n, k, T; 34 n = k = T = 0; 35 while(cin>>n>>k>>T) 36 { 37 ll s = 1, an = 1, c = n*(n+1)/2;T--; 38 while(T--) 39 { 40 an = (an + c)%k; 41 s += an; 42 c += QMul(n, n); 43 } 44 cout<<s<<endl; 45 } 46 47 return 0; 48 }
2019-01-22
12:16:49
标签:hide 开始 alt 包含 pac math ret 简单 cin
原文地址:https://www.cnblogs.com/mabeyTang/p/10303123.html