FZ操场(数学,推公式)
題目不復雜,主要是數學的計算,常用公式要熟練
寫得比較啰嗦,把整個解題過程都寫出來了,步驟都沒有省略,認真看,基本都能看懂
題目描述
一個稀疏平常的下午,潤德樓 5 樓奧賽機房里的人們正在各自做(劃)各自的事(水):
有的人打開了 majsoul:“自摸 nya,四暗刻,48000點,翻一啦”
有的人打開了 hollow knight:“小老弟,怎么回事?你的前搖怎么這么長?”
有的人打開了 tetris:“Nice!Perfect-clear!”
有的人打開了 hearth stone:“4費7-7,這卡太超模了”
而你卻打開了 qq:“…”被 czhou 爆 D 的你只好下來跑步,你發現操場是個由 n 個矩形拼接而成的圖形,且每個矩形都過一條“中軸線”。
具體來說,若將操場放在一個平面直角坐標系上,則操場可以由 n 個四元組 (x1i,y1i,x2i,y2i)表示,其中對于 i∈[2,n],y2i?1=y1i ,對于 j∈[1,n],x1i≤?1,x2i≥1。由于你劃水太多,czhou 罰你將操場的每對格點跑過去。
具體的說,每次你會選取兩個 1×1的正方形 A,B,在操場內沿著曼哈頓最短路從 A 跑到 B(格點是四連通的)。且如果你已經從 A跑到 B,則無需再從 B 跑到 A。
跑完之后,你想知道你今天跑了多長。為了體現 czhou 的良心,只需輸出答案對模 998 244 353的結果。
題目簡潔表示
n組數據,對于每一組數據,在一個平面直角坐標系上,用四元組 ( x 1 , y 1 , x 2 , y 2 ) (x1, y1, x2, y2) (x1,y1,x2,y2)來表示一個操場,現求操場中每對格子之間的曼哈頓最短路距離之和,輸出答案對模 998244353 998244353 998244353的結果。
輸入
- 第一行一個正整數 n ( n < = 1 0 6 ) n (n <= 10^6) n(n<=106),表示矩形個數。
- 第二到 n + 1 n+1 n+1 行,每行四個整數 x 1 , y 1 , x 2 , y 2 ( ∣ x 1 , y 1 , x 2 , y 2 ∣ < = 1 0 9 ) x1, y1, x2, y2( |x1,y1,x2,y2| <= 10^9) x1,y1,x2,y2(∣x1,y1,x2,y2∣<=109),表示從上到下數第 i i i 個矩形的左邊界坐標,上邊界坐標,右邊界坐標,下邊界坐標。
輸出
- 一行一個整數,表示距離之和模 998244353 998244353 998244353
樣例輸入
1 -1 1 1 -1樣例輸出
8提示
其中一共有6對格點 分別為: 黃到綠,距離為1; 黃到紫,距離為1; 黃到紅,距離為2; 綠到紫,距離為2; 綠到紅,距離為1; 紫到紅,距離為1; 所以總距離為1+1+2+2+1+1=8個人題目思路
- 需要用到的公式
-
∑ i = 1 n i = n ( n + 1 ) 2 \sum^{n}_{i = 1}{i} = \frac{n(n+1)}{2} i=1∑n?i=2n(n+1)?
-
∑ i = 1 n i 2 = n ( n + 1 ) ( 2 n + 1 ) 6 \sum^{n}_{i = 1}{i^2} = \frac{n(n+1)(2n+1)}{6} i=1∑n?i2=6n(n+1)(2n+1)?
-
∑ i = 1 n i 3 = [ n ( n + 1 ) 2 ] 2 \sum^{n}_{i = 1}{i^3} = [{\frac{n(n+1)}{2}}]^2 i=1∑n?i3=[2n(n+1)?]2
-
∑ i = 1 n i ( i + 1 ) = n ( n + 1 ) ( n + 2 ) 3 \sum^{n}_{i = 1}{i(i+1)} = \frac{n(n+1)(n+2)}{3} i=1∑n?i(i+1)=3n(n+1)(n+2)?
-
坐標給出,只是為了得出矩形的長寬,現設短邊為a,長邊為b ( a < = b ) (a <= b) (a<=b)
畫畫圖可以發現,假設 a = 4 , b = 6 a = 4, b = 6 a=4,b=6
| 2 | 3 | 4 | 5 | 6 | 7 |
| 3 | 4 | 5 | 6 | 7 | 8 |
| 4 | 5 | 6 | 7 | 8 | 9 |
從短邊對角線的方向看,可以得出,每條對角線上的元素個數
對角線1元素個數: 1
對角線2元素個數: 2
對角線3元素個數: 3
對角線4元素個數: 4
對角線5元素個數: 4
對角線6元素個數: 4
對角線7元素個數: 3
對角線8元素個數: 2
對角線9元素個數: 1
在我們計算答案的時候可以發現:
-
距離為1的點對的個數為 1 ? 2 + 2 ? 3 + 3 ? 4 + 4 ? 4 + 4 ? 4 + 4 ? 3 + 3 ? 2 + 2 ? 1 1*2+2*3+3*4+4*4+4*4+4*3+3*2+2*1 1?2+2?3+3?4+4?4+4?4+4?3+3?2+2?1
-
距離為2的點對的個數為 1 ? 3 + 2 ? 4 + 3 ? 4 + 4 ? 4 + 4 ? 3 + 4 ? 2 + 3 ? 1 1*3+2*4+3*4+4*4+4*3+4*2+3*1 1?3+2?4+3?4+4?4+4?3+4?2+3?1
但是如果這樣計算我們會發現,需要線性掃多遍才能得出答案,這樣時間復雜度是過不去的
我們又可以發現每次計算時,是有兩種對角線方向的,那么對于距離為1的點對單獨求,而對于距離大于1的點對可以只用算一遍,然后乘2即可
為了解決時間復雜度的問題,換一種計算思路可以發現:
-
在對角線2中有2個元素,其中存在1種距離為2,即答案為 2 ? 1 2 * 1 2?1
-
在對角線3中有3個元素,其中存在2種距離分別為2,4,即答案為 2 ? 2 + 4 ? 1 2 * 2 + 4 * 1 2?2+4?1
-
在對角線4中有4個元素,其中存在3種距離分別為2,4,6,即答案為 2 ? 3 + 4 ? 2 + 6 ? 1 2 * 3 + 4 * 2 + 6 * 1 2?3+4?2+6?1
-
類推下去可得:
-
對于某條對角線,其中有n個元素,即答案貢獻為 ∑ i = 1 n ? 1 2 i ( n ? i ) \sum^{n - 1}_{i = 1}{2i(n - i)} ∑i=1n?1?2i(n?i)
-
這里是沒有統計距離為1的點對的貢獻,因此需要單獨統計距離為1的點對的貢獻
- 1 ? 2 + 2 ? 3 + 3 ? 4 + 4 ? 4 + 4 ? 4 + 4 ? 3 + 3 ? 2 + 2 ? 1 1*2+2*3+3*4+4*4+4*4+4*3+3*2+2*1 1?2+2?3+3?4+4?4+4?4+4?3+3?2+2?1
-
因此最終答案為 ∑ ( 一 個 方 向 所 有 對 角 線 的 貢 獻 ) ? 2 + 距 離 為 1 的 點 對 的 貢 獻 \sum {(一個方向所有對角線的貢獻)} * 2 + 距離為1的點對的貢獻 ∑(一個方向所有對角線的貢獻)?2+距離為1的點對的貢獻
通過觀察可以發現,對于矩形 a × b a×b a×b,短邊對角線元素個數為:
1 , 2 , 3 , 4 , ? ? ? , a , a , ? ? ? , a , ? ? ? , 4 , 3 , 2 , 1 1,2,3,4,···,a,a,···,a,···,4,3,2,1 1,2,3,4,???,a,a,???,a,???,4,3,2,1 其中含有 ( b ? a + 1 ) (b-a+1) (b?a+1)個 a a a
因此所有對角線的貢獻為:
t m p 1 = 2 ? [ 2 ∑ x = 2 a ? 1 ∑ i ? 1 x ? 1 2 i ( x ? i ) + ( b ? a + 1 ) ∑ i = 1 a ? 1 2 i ( a ? i ) ] tmp1 = 2*[2\sum_{x = 2}^{a - 1}{\sum_{i - 1}^{x - 1}{2i(x - i)}} + (b-a+1)\sum_{i = 1}^{a - 1}{2i(a-i)}] tmp1=2?[2x=2∑a?1?i?1∑x?1?2i(x?i)+(b?a+1)i=1∑a?1?2i(a?i)]
距離為1的點對的貢獻為:
1 ? 2 + 2 ? 3 + ? ? ? + ( a ? 1 ) ? a + a ? a + ? ? ? + a ? a + a ? ( a ? 1 ) + ? ? ? + 3 ? 2 + 2 ? 1 1*2+2*3+···+(a-1)*a+a*a+···+a*a+a*(a-1)+···+3*2+2*1 1?2+2?3+???+(a?1)?a+a?a+???+a?a+a?(a?1)+???+3?2+2?1
= 2 ∑ i = 1 a ? 1 i ( i + 1 ) + ( b ? a ) ? a 2 = t m p 2 =2\sum_{i = 1}^{a - 1}{i(i+1)}+(b-a)*a^2=tmp2 =2i=1∑a?1?i(i+1)+(b?a)?a2=tmp2
因此最終答案為: a n s = t m p 1 + t m p 2 ans = tmp1 + tmp2 ans=tmp1+tmp2
= 2 ? [ 2 ∑ x = 2 a ? 1 ∑ i ? 1 x ? 1 2 i ( x ? i ) + ( b ? a + 1 ) ∑ i = 1 a ? 1 2 i ( a ? i ) ] + 2 ∑ i = 1 a ? 1 i ( i + 1 ) + ( b ? a ) ? a 2 = 2*[2\sum_{x = 2}^{a - 1}{\sum_{i - 1}^{x - 1}{2i(x - i)}} + (b-a+1)\sum_{i = 1}^{a - 1}{2i(a-i)}]+2\sum_{i = 1}^{a - 1}{i(i+1)}+(b-a)*a^2 =2?[2x=2∑a?1?i?1∑x?1?2i(x?i)+(b?a+1)i=1∑a?1?2i(a?i)]+2i=1∑a?1?i(i+1)+(b?a)?a2
用我們準備的公式來化簡這看似復雜的式子:
t m p 1 = 2 ? [ 2 ∑ x = 2 a ? 1 ( 2 x ∑ i = 1 x ? 1 i ? 2 ∑ i = 1 x ? 1 i 2 ) + ( b ? a + 1 ) ( 2 a ∑ i = 1 a ? 1 i ? 2 ∑ i = 1 a ? 1 i 2 ) ] tmp1 = 2*[2\sum_{x = 2}^{a - 1}{(2x\sum_{i=1}^{x-1}{i}-2\sum_{i=1}^{x-1}{i^2})} + (b-a+1)(2a\sum_{i=1}^{a-1}{i}-2\sum_{i=1}^{a-1}{i^2})] tmp1=2?[2x=2∑a?1?(2xi=1∑x?1?i?2i=1∑x?1?i2)+(b?a+1)(2ai=1∑a?1?i?2i=1∑a?1?i2)]
= 2 ? { 2 ∑ x = 2 a ? 1 [ x ? x ( x ? 1 ) ? ( x ? 1 ) x ( 2 x ? 1 ) 3 ] + ( b ? a + 1 ) [ a ? a ( a ? 1 ) ? ( a ? 1 ) a ( 2 a ? 1 ) 3 ] } = 2*\{2\sum_{x = 2}^{a - 1}{[x*x(x-1) - \frac{(x-1)x(2x-1)}{3}]} + (b-a+1)[a*a(a-1)-\frac{(a-1)a(2a-1)}{3}]\} =2?{2x=2∑a?1?[x?x(x?1)?3(x?1)x(2x?1)?]+(b?a+1)[a?a(a?1)?3(a?1)a(2a?1)?]}
= 2 ? [ 2 3 ∑ x = 2 a ? 1 ( x 3 ? x ) + ( b ? a + 1 ) ( a 3 3 ? a 3 ) ] = 2*[\frac{2}{3}\sum_{x = 2}^{a - 1}{(x^3-x)} + (b-a+1)(\frac{a^3}{3}-\frac{a}{3})] =2?[32?x=2∑a?1?(x3?x)+(b?a+1)(3a3??3a?)]
= 2 ? { 2 3 [ ∑ x = 1 a ? 1 ( x 3 ? x ) ? ( 1 ? 1 ) ] + ( b ? a + 1 ) ( a 3 3 ? a 3 ) } = 2*\{\frac{2}{3}[\sum_{x = 1}^{a - 1}{(x^3-x)}-(1 - 1)] + (b-a+1)(\frac{a^3}{3}-\frac{a}{3})\} =2?{32?[x=1∑a?1?(x3?x)?(1?1)]+(b?a+1)(3a3??3a?)}
= 2 ? [ 2 3 ( ∑ x = 1 a ? 1 x 3 ? ∑ x = 1 a ? 1 x ) + ( b ? a + 1 ) ( a 3 3 ? a 3 ) ] = 2*[\frac{2}{3}(\sum_{x=1}^{a-1}{x^3}-\sum_{x=1}^{a-1}{x}) + (b-a+1)(\frac{a^3}{3}-\frac{a}{3})] =2?[32?(x=1∑a?1?x3?x=1∑a?1?x)+(b?a+1)(3a3??3a?)]
= 2 ? { 2 3 [ ( a ? 1 ) a 2 ] 2 ? a ( a ? 1 ) 3 + ( b ? a + 1 ) ( a 3 3 ? a 3 ) } = 2*\{\frac{2}{3}[\frac{(a-1)a}{2}]^2-\frac{a(a-1)}{3} + (b-a+1)(\frac{a^3}{3}-\frac{a}{3})\} =2?{32?[2(a?1)a?]2?3a(a?1)?+(b?a+1)(3a3??3a?)}
t m p 2 = 2 ∑ i = 1 a ? 1 i ( i + 1 ) + ( b ? a ) ? a 2 tmp2=2\sum_{i = 1}^{a - 1}{i(i+1)}+(b-a)*a^2 tmp2=2i=1∑a?1?i(i+1)+(b?a)?a2
= 2 ( a ? 1 ) a ( a + 1 ) 3 + b a 2 ? a 3 =2\frac{(a-1)a(a+1)}{3}+ba^2-a^3 =23(a?1)a(a+1)?+ba2?a3
= b a 2 ? a 3 3 ? 2 3 a =ba^2-\frac{a^3}{3}-\frac{2}{3}a =ba2?3a3??32?a
那么tmp1和tmp2都可以 O ( 1 ) O(1) O(1)計算出來了,由于有分母,那么預處理一下2和3的逆元就行了
#pragma GCC optimize(3, "Ofast", "inline") #include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #include<vector> #include<ctime>using namespace std;typedef long long LL;typedef unsigned long long uLL;#define REP(i, a, b) for(register int i = (a), i##_end_ = (b); i <= i##_end_; ++ i) #define DREP(i, a, b) for(register int i = (a), i##_end_ = (b); i >= i##_end_; -- i) #define EREP(i, a) for(register int i = (be[a]); i != -1; i = nxt[i]) #define debug(...) fprintf(stderr, __VA_ARGS__) #define mem(a, b) memset((a), b, sizeof(a))template<typename T> inline bool chkmin(T &a, const T &b) { return a > b ? a = b, 1 : 0; } template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }template <class T> T read(T sum = 0, T fg = 0) {char c = getchar();while(c < '0' || c > '9') { fg |= c == '-'; c = getchar(); }while(c >= '0' && c <= '9') { sum = sum * 10 + c - '0'; c = getchar(); }return fg ? -sum : sum; }const int inf = 1e9;const LL INF = 1e17;const int Size = 3e5 + 5;const LL mod = 998244353;LL qpow(LL a, LL N) {LL ans = 1LL;while(N){if(N & 1LL) ans = ans * a % mod;a = a * a % mod;N >>= 1LL;}return ans % mod; }LL inv3, inv2;void solve() {LL x1 = read<LL>(), y1 = read<LL>(), x2 = read<LL>(), y2 = read<LL>();LL a = x2 - x1, b = y2 - y1;if(a < 0) a = -a;if(b < 0) b = -b;if(a > b) swap(a, b);LL ans = ((qpow(a, 3) * inv3 % mod - a * inv3 % mod) % mod + mod) % mod;ans = ans * (b - a + 1) % mod;LL tmp = qpow((a - 1) * a % mod * inv2 % mod, 2) * 2LL % mod * inv3 % mod;tmp = (((tmp - a * (a - 1) % mod * inv3 % mod) % mod) + mod) % mod;ans = (ans + tmp) * 2LL % mod;ans = (ans + (a - 1) * a % mod * (a + 1) % mod * inv3 % mod * 2LL % mod) % mod;ans = (ans + (b - a) * qpow(a, 2) % mod) % mod;printf("%lld\n", (tmp + ans) % mod); }int main() { #ifndef ONLINE_JUDGEfreopen("input.in", "r", stdin);freopen("output.out", "w", stdout); #endifinv2 = qpow(2, mod - 2);inv3 = qpow(3, mod - 2);int n = read<int>();while(n--) solve();return 0; }第一次寫這么復雜的數學題,代碼簡單,主要還是推式子
總結
以上是生活随笔為你收集整理的FZ操场(数学,推公式)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: My Plan
- 下一篇: 给ChatGLM2注入知识;阅文集团发布