AT1278 Counting on a Triangle 题解
題意
一個第 nnn 行有 nnn 個點的矩陣,其規律為每個點的值為每個點橫坐標與縱坐標的乘積,求第 AAA 行到第 BBB 行所有點的值的和(包括 AAA,BBB 兩行),結果 mod1000000007\mod1000000007mod1000000007。
暴力做法
枚舉每個數并累加取模即可,顯然,復雜度 Θ(n2)\Theta(n^2)Θ(n2) 的暴力會 TLE,因為數據范圍是 10610^6106。
優化
仔細觀察這個矩陣,我們可以一行一行考慮,
對于第 nnn 行,每個點的坐標分別為 (1,n),(2,n),(3,n)?(n?1,n),(n,n)(1,n),(2,n),(3,n)\cdots(n-1,n),(n,n)(1,n),(2,n),(3,n)?(n?1,n),(n,n),
這些點的值的和為 n+2n+3n+?+(n?1)n+n2n + 2n + 3n + \cdots + (n-1)n + n^2n+2n+3n+?+(n?1)n+n2,
提取公因數后得 n(1+2+3+?+n?1+n)n(1 + 2 + 3 + \cdots + n-1 + n)n(1+2+3+?+n?1+n),
因此問題就轉化為了求這個等差數列的和。
運用我們數學課的知識,對一個等差數列求和,其公式為 n(n+1)2\frac{n(n+1)}{2}2n(n+1)?。
再回到暴力解法,原來的第二層循環就可以替換為等差數列求和,這時就只有一重循環了,時間復雜度 Θ(n)\Theta(n)Θ(n)。
代碼
分析之后代碼就很好寫了,注意取模,雖然答案再 int 范圍內,但是在計算過程中可能會超出 int 范圍,所以開 long long 會更保險。
#include<bits/stdc++.h> using namespace std; #define ll long long const int mod = 1000000007; ll a, b, ans; int main() {scanf("%lld%lld", &a, &b);for(ll i = a; i <= b; i++) {ans += (i * (i * (i + 1) / 2) % mod) % mod;ans %= mod;}printf("%lld\n", ans);return 0; }總結
以上是生活随笔為你收集整理的AT1278 Counting on a Triangle 题解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux的引导过程与服务控制
- 下一篇: 如何用C语言和Python编写一个BMI