p1637三元上公升子串行
提交 討論 題解
最新討論更多討論
題目描述
erwin最近對一種叫"thair"的東西巨感興趣。。。
在含有n個整數的序列a1,a2......an中,
三個數被稱作"thair"當且僅當i求乙個序列中"thair"的個數。
輸入輸出格式
輸入格式:
開始乙個正整數n,
以後n個數a1~an。
輸出格式:
"thair"的個數
輸入輸出樣例
輸入樣例#1:
input
42 1 3 4
output
2input
51 2 2 3 4
output
7對樣例2的說明:
7個"thair"分別是
1 2 3
1 2 4
1 2 3
1 2 4
1 3 4
2 3 4
2 3 4
輸出樣例#1:
說明
約定 30%的資料n<=100
60%的資料n<=2000
100%的資料n<=30000
大資料隨機生成
0<=a[i]<=maxlongint
分析:這道題可以借鑑之前求逆序對那樣求,我們只需要求對於每乙個數i,在i之前比i小的數的個數和在i之後比i大的數的個數,相乘起來,最後將所有結果加起來就是答案,關鍵就是如何求出這些數的個數。可以利用樹狀陣列。先將資料離散化,先找小於i的,因為要嚴格小於,所以我們要先-1再查詢,然後新增進去,然後找大於i的,從後往前列舉,相當於我們找到i之後不大於i的個數,然後用n-i(i之後的數的個數)減去結果就是嚴格大於i的數的個數,最後統計一下答案即可。
如果將這道題推廣到要找k個數的情況,我們需要用到dp,則dp[i][j] = dp[k][j-1] + dp[k][j],其中k為小於i中最靠後的乙個數.
#include #include#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
long
long d1[30010], d2[30010],ans1[30010],ans2[30010],dis[30010
],ans;
struct
node
a[30010
];int
n;void update(long
long x, intv)}
int sum(long
long
x)
return
cnt;
}void update2(long
long x, intv)}
int sum2(long
long
x)
return
cnt;
}bool
cmp(node a, node b)
intmain()
sort(a + 1, a + 1 +n, cmp);
dis[a[
1].id] = 1
;
int tot = 1
;
for (int i = 2; i <= n; i++)
for (int i = 1; i <= n; i++)
for (int i = n; i >= 1; i--)
for (int i = 1; i <= n; i++)
ans += ans1[i] *ans2[i];
printf(
"%lld\n
", ans);
return0;
}
三元上公升子串行 洛谷p1637
erwin最近對一種叫 thair 的東西巨感興趣。在含有n個整數的序列a1,a2.an中,三個數被稱作 thair 當且僅當i求乙個序列中 thair 的個數。輸入格式 開始乙個正整數n,以後n個數a1 an。輸出格式 thair 的個數 輸入樣例 1 4 50 18 3 4 6 8 1415 1...
P1637 三元上公升子串行
標籤 線段樹 離散化好題。題意 給定乙個長度為 首先,我們知道求滿足 那麼對於原問題,include include include define ri register int using namespace std const int maxn 30020 int n,a maxn int l ...
P1637 三元上公升子串行
對於這個題,我們對於每乙個數i,分別求出所有比它小的,在它前面的和 比它大的,在它後面的,然後把這兩個乘起來,然後再把這些積加起來就可以了 然而這樣直接做複雜度太高了,我們要優化,仿照樹狀陣列求逆序對的方法,我們就可以在可以接受的時間內求出並且解決問題了 include include includ...