矩形並(2020強智杯)
阿新 • • 發佈:2021-01-19
題目連結:https://ac.nowcoder.com/acm/contest/9699/H
題目描述:
Bobo 有一個矩形A。舉行的左下角座標是 (x1, y1),右上角座標是 (x2, y2)。設 R(i, j) 是左下角座標是 (0, 0),右上角座標是 (i, j) 的矩形,Area(i, j) 是矩形 A 和矩形 R(i, j) 的並的面積。給出 a 和 b,求:∑i=1a∑j=1bArea(i,j)除以 (109+ 7) 的餘數。
輸入描述:
輸入檔案包含多組資料,請處理到檔案結束。 每組資料的第一行包含兩個整數 a 和 b,第二行包含四個整數 x1, x2, y1, y2. ·1 ≤ a, b, x1, x2, y1, y2 ≤ 109 · x1 < x2 , y1 < y2 · 資料組數不超過 104
輸出描述:
對於每組資料,輸出一個整數,表示所求的值。
示例:
輸入: 1 1 2 3 2 3 10 10 1 5 1 5 1000000000 1000000000 1 1000000000 1 1000000000 輸出: 2 3725 2793
題目分析:
1,先不論題目,本題有一個要求結果 “(109+ 7) 的餘數”。
因為如果mod簡單的數理論上會增大演算法錯誤但是由於巧合恰好模出相等的數,而AC的概率
而1e9+7這個數是素數,相加不爆int,相乘不爆ll。
所以由於在運算過程中說有數都可能爆ll所以在相加相乘的時候要隨時餘mod!
2,在算數運算子的左側如果運算數num都是int型別而運算子右側都是long long型時,運算子右側運算數 num 需要* 1LL
*1LL是為了在計算時,把int型別的變數轉化為long long
,然後再賦值給long long
型別的變數
例如,long long ans = 0;
ans
是long long
型別的,
ans += num * 1LL * (num - 1) / 2;
不至於後面計算溢位,* 1LL
之後型別就轉換為long long
, num變數是定義為int
型別的。
3.在寫題時,看到階乘符號,首先想到的是使用while把結果累加。
而實際上可以直接使用數列求和公式直接把結果算出來,從而降低時間複雜度。
程式碼:
c:
#include<cstdio> typedef long long ll; const ll mod = 1e9 + 7; ll all(ll xx, ll yy) { return xx * (xx + 1) / 2 % mod * (yy * (yy + 1) / 2 % mod) % mod; } int main() { ll a, b; ll x1, y1, x2, y2; while (~scanf("%lld %lld %lld %lld %lld %lld", &a, &b, &x1, &x2, &y1, &y2)) { ll ans = 0; ans += all(a, b) % mod; ans = (ans + a * b % mod * (x2 - x1) % mod * (y2 - y1) % mod) % mod; if (x1 < a && y1 < b) { ll x = a - x1, y = b - y1; ans = (ans + mod - all(x, y)) % mod; if (x2 < a) { ll xx = a - x2; ans = (ans + all(xx, y)) % mod; } if (y2 < b) { ll yy = b - y2; ans = (ans + all(x, yy)) % mod; if (x2 < a) { ll xx = a - x2; ans = (ans + mod - all(xx, yy)) % mod; } } } printf("%lld\n", ans); } return 0; }