日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDU4000Fruit Ninja【树状数组+组合数】

發布時間:2025/5/22 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU4000Fruit Ninja【树状数组+组合数】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

大意:

告訴你一個有n個數的序列 (1 -- n) 問其中有多少組 (a[i], a[j], a[k]) 滿足i < j < k 并且 a[i] < a[k] < a[j]

?

分析:

這個題跟那個中間為峰值的題很像 ? 我的第一反應為樹狀數組

求的就是在這個序列當中 ?小大中 一共會出現多少次

小大中 = (小中大 + 小大中) — 小中大

(小中大 + 小大中) 也就是說只要前面這個數是小的 ?后面的大的數中任取兩個就可以了

用兩個數組來維護

一個qian[]用來存前邊有多少個小于這個數 ?另一個hou[]維護后面有多少個大于這個數

小中大的個數就是 ?sum(qian[i] * hou[i])==

求小XX的過程中我腦袋抽筋了

我一開始用的是這種思路

對于每一位

用比它小的個數 * (C(大于它的g個數, 2)) ?

看起來貌似很合理

但是其實有個嚴重的問題

在求小中大的過程我們可以那么考慮是因為中間的是唯一的

所以無論我們怎么成都不會重復

但是這個若只是考慮小于它的和大于等于它的想成就會出現重復的

怎么避免重復呢

只要按照求小中大的思路

我們可以確定一個最小的 ?那么 ?之后的就是以這個為基準的 而不會出現重復

小XX = sum(C(大于該位, 2) );

?

代碼:

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 const long long maxn = 100005; 7 const long long mod = 100000007; 8 long long c[maxn]; 9 long long n, a[maxn]; 10 long long qian[maxn], hou[maxn], hh[maxn]; 11 12 long long lowbit(long long x) { 13 return x & ( - x ) ; 14 } 15 16 void add(long long i) { 17 while(i <= n) { 18 c[i] += 1; 19 i += lowbit(i); 20 } 21 } 22 23 long long sum(long long i) { 24 long long s = 0; 25 while(i > 0) { 26 s += c[i]; 27 i -= lowbit(i); 28 } 29 return s; 30 } 31 32 void init() { 33 memset(c, 0, sizeof(c)); 34 for(long long i = 1; i <= n; i++) { 35 qian[i] = sum(a[i]); 36 add(a[i]); 37 } 38 memset(c, 0, sizeof(c)); 39 for(long long i = n; i >= 1; i--) { 40 add(a[i]); 41 hou[i] = n - i + 1 - sum(a[i]); 42 } 43 } 44 45 int main() { 46 long long t; 47 scanf("%I64d",&t); 48 for(long long kase = 1; kase <= t; kase++) { 49 scanf("%I64d",&n); 50 for(long long i = 1; i <= n; i++) scanf("%I64d",&a[i]); 51 init(); 52 long long sum1 = 0; 53 for(long long i = 1; i <= n; i++) { 54 sum1 += qian[i] * hou[i]; 55 sum1 %= mod; 56 } 57 long long sum2 = 0; 58 for(long long i = 1; i <= n; i++) { 59 sum2 += (hou[i] * (hou[i] - 1) / 2); 60 sum2 %= mod; 61 } 62 printf("Case #%I64d: ", kase); 63 long long ans = (sum2 - sum1 + mod) % mod; 64 printf("%I64d\n", ans); 65 } 66 return 0; 67 } View Code

?

轉載于:https://www.cnblogs.com/zhanzhao/p/4031933.html

總結

以上是生活随笔為你收集整理的HDU4000Fruit Ninja【树状数组+组合数】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。